1 // RUN: %clang_cc1 -std=c++2a -x c++ %s -verify 2 3 // Test parsing of the optional requires-clause in a template-declaration. 4 5 template <typename T> requires true foo()6void foo() { } 7 8 template <typename T> requires (!0) 9 struct A { 10 void foo(); 11 struct AA; 12 enum E : int; 13 static int x; 14 15 template <typename> requires true 16 void Mfoo(); 17 18 template <typename> requires true 19 struct M; 20 21 template <typename> requires true 22 static int Mx; 23 24 template <typename TT> requires true 25 using MQ = M<TT>; 26 }; 27 28 template <typename T> requires (!0) foo()29void A<T>::foo() { } 30 31 template <typename T> requires (!0) 32 struct A<T>::AA { }; 33 34 template <typename T> requires (!0) 35 enum A<T>::E : int { E0 }; 36 37 template <typename T> requires (!0) 38 int A<T>::x = 0; 39 40 template <typename T> requires (!0) 41 template <typename> requires true Mfoo()42void A<T>::Mfoo() { } 43 44 template <typename T> requires (!0) 45 template <typename> requires true 46 struct A<T>::M { }; 47 48 template <typename T> requires (!0) 49 template <typename> requires true 50 int A<T>::Mx = 0; 51 52 template <typename T> requires true 53 int x = 0; 54 55 template <typename T> requires true 56 using Q = A<T>; 57 58 struct C { 59 template <typename> requires true 60 void Mfoo(); 61 62 template <typename> requires true 63 struct M; 64 65 template <typename> requires true 66 static int Mx; 67 68 template <typename T> requires true 69 using MQ = M<T>; 70 }; 71 72 template <typename> requires true Mfoo()73void C::Mfoo() { } 74 75 template <typename> requires true 76 struct C::M { }; 77 78 template <typename> requires true 79 int C::Mx = 0; 80 81 // Test behavior with non-primary-expression requires clauses 82 83 template<typename T> requires foo<T>() 84 // expected-error@-1{{parentheses are required around this expression in a requires clause}} 85 struct B1 { }; 86 func()87int func() { } 88 89 template<typename T> requires func() 90 // expected-error@-1{{atomic constraint must be of type 'bool' (found '<overloaded function type>')}} 91 // expected-note@-2{{parentheses are required around this expression in a requires clause}} 92 struct B2 { }; 93 94 template<typename T> requires (foo<T>()) 95 struct B3 { }; 96 97 template<typename T> requires T{} 98 // expected-error@-1{{parentheses are required around this expression in a requires clause}} 99 struct B4 { }; 100 101 template<typename T> requires sizeof(T) == 0 102 // expected-error@-1{{parentheses are required around this expression in a requires clause}} 103 struct B5 { }; 104 105 template<typename T> requires (sizeof(T)) == 0 106 // expected-error@-1{{parentheses are required around this expression in a requires clause}} 107 struct B6 { }; 108 109 template<typename T> requires 0 110 // expected-error@-1{{atomic constraint must be of type 'bool' (found 'int')}} bar()111(int) bar() { }; 112 foo(int)113template<typename T> requires foo<T> 114 (int) bar() { }; 115 // expected-error@-1{{expected '(' for function-style cast or type construction}} 116 117 template<typename T> 118 void bar() requires foo<T>(); 119 // expected-error@-1{{parentheses are required around this expression in a requires clause}} 120 121 template<typename T> 122 void bar() requires (foo<T>()); 123 124 template<typename T> 125 void bar() requires func(); 126 // expected-error@-1{{atomic constraint must be of type 'bool' (found '<overloaded function type>')}} 127 // expected-note@-2{{parentheses are required around this expression in a requires clause}} 128 129 template<typename T> bar()130void bar() requires T{}; 131 // expected-error@-1{{parentheses are required around this expression in a requires clause}} 132 133 template<typename T> 134 void bar() requires sizeof(T) == 0; 135 // expected-error@-1{{parentheses are required around this expression in a requires clause}} 136 137 template<typename T> 138 void bar() requires (sizeof(T)) == 0; 139 // expected-error@-1{{parentheses are required around this expression in a requires clause}} 140 141 void bar(int x, int y) requires (x, y, true); 142 143 struct B { 144 int x; 145 void foo(int y) requires (x, this, this->x, y, true); 146 static void bar(int y) requires (x, true); 147 // expected-error@-1{{'this' cannot be implicitly used in a static member function declaration}} 148 static void baz(int y) requires (this, true); 149 // expected-error@-1{{'this' cannot be used in a static member function declaration}} 150 }; 151 152 auto lambda1 = [] (auto x) requires (sizeof(decltype(x)) == 1) { }; 153 154 auto lambda2 = [] (auto x) constexpr -> int requires (sizeof(decltype(x)) == 1) { return 0; }; 155 156 auto lambda3 = [] requires (sizeof(char) == 1) { }; 157 // expected-error@-1{{lambda requires '()' before 'requires' clause}}