1 // { dg-do compile { target c++2a } } 2 3 template<typename T> 4 concept Class = __is_class(T); 5 6 // Allow a requires-expression with no parms. 7 template<typename T> 8 concept C = requires { typename T::type; }; 9 10 void f1(int a) requires true; // { dg-error "non-templated" } 11 auto f2(int a) -> bool requires true; // { dg-error "non-templated" } 12 auto f3(int a) requires true -> bool; // { dg-error "" } requires-clause precedes trailing-return-type 13 typedef void fn_t() requires true; // { dg-error "typedef" } 14 void (*pf)() requires true; // { dg-error "non-function" } 15 void (*fn(int))() requires false; // { dg-error "return type" } 16 void g(int (*)() requires true); // { dg-error "parameter|non-function" } 17 auto* p = new (void(*)(char) requires true); // { dg-error "type-id" } f4(auto a)18void f4(auto a) requires Class<decltype(a)> { } f5(auto a)19void f5(auto a) requires requires (decltype(a) x) { -x; } { } // { dg-message "in requirements" } 20 21 struct Test { 22 void f(auto a) requires Class<decltype(a)>; 23 } test; 24 driver_1()25void driver_1() { 26 struct S { } s; 27 f4(s); 28 f5(0); 29 f5((void*)0); // { dg-error "" } 30 test.f(s); 31 } 32 f(auto a)33void Test::f(auto a) requires Class<decltype(a)> { } 34 35 template<bool B> requires B struct S0; // OK 36 37 template<int N> requires N struct S1 { }; // { dg-error "does not have type" } 38 S1<1> x0; // { dg-error "template constraint failure|does not have type" } 39 40 template<int N> requires N == 0 struct S2 { }; // { dg-error "does not have type|must be enclosed" } 41 42 template<int N> requires (N == 0) struct S3 { }; // OK 43 44 template<typename T, T X> requires X struct S4 { }; // { dg-error "bool" } 45 S4<int, 0> x1; // { dg-error "template constraint failure" } 46 S4<bool, true> x2; // OK 47 S4<bool, false> x3; // { dg-error "template constraint failure" } 48 49 50 // req11.C 51 template<typename T> requires(T t)52concept Streamable = requires (T t) { t; }; 53 54 template<typename T> requires(T t)55concept Range = requires (T t) { t; }; 56 57 // FIXME: There are two syntax errors here when there should be 58 // just one.Note that !Range<T> is not a primary-expression and needs to 59 // be wrapped in parens to be syntactically valid. 60 template<class T> 61 requires Streamable<T> && !Range<T> // { dg-error "must be enclosed" } 62 void print1(const T& x) { } 63 64 template<class T> 65 requires Streamable<T> && (!Range<T>) print2(const T & x)66void print2(const T& x) { } 67 driver_3()68void driver_3() 69 { 70 print2("hello"); // { dg-error "" } 71 } 72