1 // RUN: %clang_cc1 -std=c++20 -x c++ %s -verify 2 // RUN: %clang_cc1 -std=c++23 -x c++ %s -verify 3 4 // Test parsing of the optional requires-clause in a template-declaration. 5 6 template <typename T> requires true 7 void foo() { } 8 9 template <typename T> requires (!0) 10 struct A { 11 void foo(); 12 struct AA; 13 enum E : int; 14 static int x; 15 static constexpr int z = 16; 16 17 template <typename> requires true 18 void Mfoo(); 19 20 template <typename> requires true 21 struct M; 22 23 template <typename> requires true 24 static int Mx; 25 26 template <typename TT> requires true 27 using MQ = M<TT>; 28 29 constexpr int bazz() requires (z == 16); 30 }; 31 32 template <typename T> requires (!0) 33 void A<T>::foo() { } 34 35 template <typename T> requires (!0) 36 struct A<T>::AA { }; 37 38 template <typename T> requires (!0) 39 enum A<T>::E : int { E0 }; 40 41 template <typename T> requires (!0) 42 int A<T>::x = 0; 43 44 template <typename T> requires (!0) 45 template <typename> requires true 46 void A<T>::Mfoo() { } 47 48 template <typename T> requires (!0) 49 template <typename> requires true 50 struct A<T>::M { }; 51 52 template <typename T> requires (!0) 53 template <typename> requires true 54 int A<T>::Mx = 0; 55 56 template <typename T> requires true 57 int x = 0; 58 59 template <typename T> requires true 60 using Q = A<T>; 61 62 template<typename T> requires (!0) 63 constexpr int A<T>::bazz() requires (z == 16) { return z; } 64 65 struct C { 66 template <typename> requires true 67 void Mfoo(); 68 69 template <typename> requires true 70 struct M; 71 72 template <typename> requires true 73 static int Mx; 74 75 template <typename T> requires true 76 using MQ = M<T>; 77 }; 78 79 template <typename> requires true 80 void C::Mfoo() { } 81 82 template <typename> requires true 83 struct C::M { }; 84 85 template <typename> requires true 86 int C::Mx = 0; 87 88 // Test behavior with non-primary-expression requires clauses 89 90 template<typename T> requires foo<T>() 91 // expected-error@-1{{parentheses are required around this expression in a requires clause}} 92 struct B1 { }; 93 94 int func() { } 95 96 template<typename T> requires func() 97 // expected-error@-1{{atomic constraint must be of type 'bool' (found '<overloaded function type>')}} 98 // expected-note@-2{{parentheses are required around this expression in a requires clause}} 99 struct B2 { }; 100 101 template<typename T> requires (foo<T>()) 102 struct B3 { }; 103 104 template<typename T> requires T{} 105 // expected-error@-1{{parentheses are required around this expression in a requires clause}} 106 struct B4 { }; 107 108 template<typename T> requires sizeof(T) == 0 109 // expected-error@-1{{parentheses are required around this expression in a requires clause}} 110 struct B5 { }; 111 112 template<typename T> requires (sizeof(T)) == 0 113 // expected-error@-1{{parentheses are required around this expression in a requires clause}} 114 struct B6 { }; 115 116 template<typename T> requires 0 117 // expected-error@-1{{atomic constraint must be of type 'bool' (found 'int')}} 118 (int) bar() { }; 119 120 template<typename T> requires foo<T> 121 (int) bar() { }; 122 // expected-error@-1{{expected '(' for function-style cast or type construction}} 123 124 template<typename T> 125 void bar() requires foo<T>(); 126 // expected-error@-1{{parentheses are required around this expression in a requires clause}} 127 128 template<typename T> 129 void bar() requires (foo<T>()); 130 131 template<typename T> 132 void bar() requires func(); 133 // expected-error@-1{{atomic constraint must be of type 'bool' (found '<overloaded function type>')}} 134 // expected-note@-2{{parentheses are required around this expression in a requires clause}} 135 136 template<typename T> 137 void bar() requires T{}; 138 // expected-error@-1{{parentheses are required around this expression in a requires clause}} 139 140 template<typename T> 141 void bar() requires sizeof(T) == 0; 142 // expected-error@-1{{parentheses are required around this expression in a requires clause}} 143 144 template<typename T> 145 void bar() requires (sizeof(T)) == 0; 146 // expected-error@-1{{parentheses are required around this expression in a requires clause}} 147 148 template<typename T> 149 void bar(int x, int y) requires (x, y, true); 150 151 template<typename T> 152 struct B { 153 int x; 154 void foo(int y) requires (x, this, this->x, y, true); 155 static void bar(int y) requires (x, true); 156 // expected-error@-1{{'this' cannot be implicitly used in a static member function declaration}} 157 static void baz(int y) requires (this, true); 158 // expected-error@-1{{'this' cannot be used in a static member function declaration}} 159 }; 160 161 auto lambda1 = [] (auto x) requires (sizeof(decltype(x)) == 1) { }; 162 163 auto lambda2 = [] (auto x) constexpr -> int requires (sizeof(decltype(x)) == 1) { return 0; }; 164 165 auto lambda3 = []<auto> requires(sizeof(char) == 1){}; 166 167 auto lambda4 = [] requires(sizeof(char) == 1){}; // expected-error {{expected body of lambda expression}} 168 #if __cplusplus <= 202002L 169 // expected-warning@-2{{lambda without a parameter clause is a C++23 extension}} 170 #endif 171 172 namespace GH78524 { 173 174 template <typename T> T Foo; 175 176 template <typename T> auto C(Foo<T>); 177 178 template <typename T> struct D { 179 decltype(T()(C<T>)) Type; 180 }; 181 182 template <typename T, typename U> D<T> G(T, U) { return {}; } 183 184 struct E {}; 185 186 void F() { 187 G([]<typename T> 188 // ~~~~~~~~~~ T: Depth: 0, Index: 0 189 requires requires { [](auto...) {}; }(T) 190 // ~~~~ auto: Depth: 1, Index: 0 191 { return T(); }, 192 E{}); 193 } 194 195 int a = []<int=0> requires requires { [](auto){}; } { return 0; }(); 196 197 } // namespace GH78524 198 199 200 namespace GH51868 { 201 template<auto L> 202 concept C = requires { 203 typename decltype(L)::template operator()<int>; 204 // expected-error@-1 {{template name refers to non-type template 'decltype(L)::template operator ()'}} 205 }; 206 } 207