work with the standard. */
if (cxx_dialect >= cxx20 || flag_concepts_ts)
flag_concepts = 1;
- else if (flag_concepts)
- /* For -std=c++17 -fconcepts, imply -fconcepts-ts. */
- flag_concepts_ts = 1;
if (num_in_fnames > 1)
error ("too many filenames given; type %<%s %s%> for usage",
else if (cxx_dialect >= cxx11
&& cp_lexer_next_token_is_keyword (parser->lexer, RID_USING))
decl = cp_parser_alias_declaration (parser);
- else if (cxx_dialect >= cxx20 /* Implies flag_concept. */
+ else if (flag_concepts
&& cp_lexer_next_token_is_keyword (parser->lexer, RID_CONCEPT)
- && !cp_lexer_nth_token_is_keyword (parser->lexer, 2, RID_BOOL))
- /* Allow 'concept bool' to be handled as per the TS. */
+ && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
+ /* -fconcept-ts 'concept bool' syntax is handled below, in
+ cp_parser_single_declaration. */
decl = cp_parser_concept_definition (parser);
else
{
@itemx -fconcepts-ts
@opindex fconcepts
@opindex fconcepts-ts
-Below @option{-std=c++20}, @option{-fconcepts} enables support for the
-C++ Extensions for Concepts Technical Specification, ISO 19217 (2015).
-
-With @option{-std=c++20} and above, Concepts are part of the language
-standard, so @option{-fconcepts} defaults to on. But the standard
-specification of Concepts differs significantly from the TS, so some
-constructs that were allowed in the TS but didn't make it into the
-standard can still be enabled by @option{-fconcepts-ts}.
+Enable support for the C++ Concepts feature for constraining template
+arguments. With @option{-std=c++20} and above, Concepts are part of
+the language standard, so @option{-fconcepts} defaults to on.
+
+Some constructs that were allowed by the earlier C++ Extensions for
+Concepts Technical Specification, ISO 19217 (2015), but didn't make it
+into the standard, can additionally be enabled by
+@option{-fconcepts-ts}.
@item -fconstexpr-depth=@var{n}
@opindex fconstexpr-depth
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class T1, class T2> class A { };
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class...> class tuple {};
// PR c++/85006
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename... Ts> struct A {};
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class T>
concept bool Isint = __is_same_as(T,int);
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool One() { return sizeof(T) >= 4; }
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool One() { return sizeof(T) >= 4; }
// PR c++/84551
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename> concept bool C() { return true; }
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
typedef concept int CINT; // { dg-error "'concept' cannot appear in a typedef declaration" }
// PR c++/67007
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class U>
concept bool A =
// PR c++/67159
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts -fconcepts-diagnostics-depth=2" }
+// { dg-options "-fconcepts-ts -fconcepts-diagnostics-depth=2" }
template <class T, class U>
concept bool SameAs = __is_same_as(T, U);
// PR c++/66092
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
#include <type_traits>
// { dg-do link { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
// Check equivalence of short- and longhand declarations.
// { dg-do link { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
// template<typename T>
// { dg-do run { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
// TODO: ICE on gimplify 16?
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C1()
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C()
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool Tuple() { // { dg-error "multiple statements" }
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept auto C1() { return 0; } // { dg-error "16:concept .concept auto C1\\(\\). declared with a deduced return type" }
// PR c++/92746
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T> concept bool C3() { return true; }
static_assert(noexcept(C3<int>()), "function concept should be treated as if noexcept(true) specified");
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C() { return __is_class(T); }
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
// Test that constraint satisfaction checks work even when
// processing template declarations.
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C() { return __is_class(T); }
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
#include <cassert>
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C() { return __is_class(T); }
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
// Check shorthand notation.
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
// Redefinition errors.
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool Class() { return __is_class(T); }
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
#include <cassert>
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C() { return __is_class(T); }
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
#include <cassert>
#include <type_traits>
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C = __is_class(T);
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C() { return __is_class(T); }
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C = __is_class(T);
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
#include <cassert>
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename ... T>
concept bool C1 = true;
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename ... T>
concept bool C1 = true;
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T, typename U = int>
concept bool C()
// PR c++/67003
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
namespace X {
template<class>
// PR c++/66985
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <template <class> class T>
concept bool Valid = requires { typename T<int>; };
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
struct S
{
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool Type = true;
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
// Make sure that we check partial concept ids
// with variable concepts.
// PR c++/67138
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class T>
concept bool _Auto = true;
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C1 = sizeof(T) == 0;
// PR c++/66218
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class T, class U>
concept bool Same = __is_same_as(T, U);
// PR c++/66218
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class T, class U>
concept bool Same = __is_same_as(T, U);
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class T, class U>
concept bool Same = __is_same_as(T, U);
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <int I> struct B { static const int i = I; };
template <int I> concept bool Few = I < 10;
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C1() {
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
using TD = int;
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C = requires (T t) { t.mf(); };
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
// Performance test... This should be fast.
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<class T> concept bool C1 = true;
template<class A, class B> struct Pair {};
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class X> concept bool allocatable = requires{{new X}->X *; };
template <class X> concept bool semiregular = allocatable<X>;
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class>
concept bool C1 () {
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<template<typename> class T>
concept bool C = T<int>::value;
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C() { return true; }
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<template<typename> class T>
concept bool C = true;
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<class T>
concept bool Addable(){
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<int> concept bool C = true;
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool NameProvider()
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
// Conceptized version of template/ttp23.C
template <class T> concept bool Foo = true;
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C1 = __is_same_as(T, int);
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C1 = __is_same_as(T, int);
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C1 = __is_same_as(T, int);
// PR c++/66937
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
#include <tuple>
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C1 = __is_class(T);
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C1 = __is_class(T);
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T>
concept bool C1 = __is_class(T);
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T, typename U>
concept bool Same = __is_same_as(T, U);
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename T1, typename T2>
concept bool C1 = true;
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class T>
concept int C = true; // { dg-error "bool" }
// PR c++/85133
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename> concept bool C; // { dg-error "no initializer" }
// PR c++/67139
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class T>
constexpr typename T::type::value_type _v = T::type::value;
// PR c++/68666
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
struct A {
template <class>
// PR c++/66712
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class T, class...Args>
concept bool _Constructible_ =
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class T> concept bool Copyable = requires (T t) { T(t); };
template <class T> concept bool Constructable = requires { T(); };
// PR c++/70036
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template <class T> concept bool C = true;
// PR c++/73456
// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts" }
+// { dg-options "-fconcepts-ts" }
template<typename...> struct list {};
// PR c++/65575
// { dg-do compile { target c++17_only } }
-// { dg-additional-options "-fconcepts" }
+// { dg-additional-options "-fconcepts-ts" }
template<typename T>
concept bool C = false;
// PR c++/66091
// { dg-do compile { target c++17_only } }
-// { dg-additional-options "-fconcepts" }
+// { dg-additional-options "-fconcepts-ts" }
template<typename T>
concept bool C1()
template <typename T>
void foo1(T& t) {
typename T::template C<void> tcv = t;
- typename T::template C<auto> u = tcv; // { dg-error "" "" { target c++20 } }
+ typename T::template C<auto> u = tcv; // { dg-error "" }
T::template C<auto>::f (tcv, u); // { dg-error "" }
(typename T::template D<auto> (t)); // { dg-error "" }
-// { dg-warning "only available" "" { target c++17_down } .-1 }
}
struct T1 {
template <typename T>
void foo2(T& t) {
typename T::template C<void> tcv = t;
- typename T::template C<auto> u = tcv; // { dg-error "" "" { target c++20 } }
+ typename T::template C<auto> u = tcv; // { dg-error "" }
T::template C<auto>::f (tcv, u); // { dg-error "" }
T::template D<auto> (t); // { dg-error "" }
}
template <typename T>
void foo1(T& t) {
typename T::template C<void> tcv = t;
- typename T::template C<auto> u = tcv; // { dg-error "" "" { target c++20 } }
+ typename T::template C<auto> u = tcv; // { dg-error "" }
T::template C<auto>::f (tcv, u); // { dg-error "" }
(typename T::template D<auto> (t)); // { dg-error "" }
-// { dg-warning "only available" "" { target c++17_down } .-1 }
}
struct T1 {
template <typename T>
void foo2(T& t) {
typename T::template C<void> tcv = t;
- typename T::template C<auto> u = tcv; // { dg-error "" "" { target c++20 } }
+ typename T::template C<auto> u = tcv; // { dg-error "" }
T::template C<auto>::f (tcv, u); // { dg-error "" }
T::template D<auto> (t); // { dg-error "" }
}
// { dg-do compile { target c++17_only } }
-// { dg-additional-options "-fconcepts" }
+// { dg-additional-options "-fconcepts-ts" }
template<T> concept bool C = true; // { dg-error "has not been declared" }
// PR c++/85265
// { dg-do compile { target c++17_only } }
-// { dg-additional-options "-fconcepts" }
+// { dg-additional-options "-fconcepts-ts" }
template<typename> concept bool C = true;