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