1 // RUN: %clang_cc1 -std=c++20 -x c++ %s -verify
2 // RUN: %clang_cc1 -std=c++23 -x c++ %s -verify
4 // Test parsing of the optional requires-clause in a template-declaration.
6 template <typename T
> requires
true
9 template <typename T
> requires (!0)
15 static constexpr int z
= 16;
17 template <typename
> requires
true
20 template <typename
> requires
true
23 template <typename
> requires
true
26 template <typename TT
> requires
true
29 constexpr int bazz() requires (z
== 16);
32 template <typename T
> requires (!0)
35 template <typename T
> requires (!0)
38 template <typename T
> requires (!0)
39 enum A
<T
>::E
: int { E0
};
41 template <typename T
> requires (!0)
44 template <typename T
> requires (!0)
45 template <typename
> requires
true
48 template <typename T
> requires (!0)
49 template <typename
> requires
true
52 template <typename T
> requires (!0)
53 template <typename
> requires
true
56 template <typename T
> requires
true
59 template <typename T
> requires
true
62 template<typename T
> requires (!0)
63 constexpr int A
<T
>::bazz() requires (z
== 16) { return z
; }
66 template <typename
> requires
true
69 template <typename
> requires
true
72 template <typename
> requires
true
75 template <typename T
> requires
true
79 template <typename
> requires
true
82 template <typename
> requires
true
85 template <typename
> requires
true
88 // Test behavior with non-primary-expression requires clauses
90 template<typename T
> requires foo
<T
>()
91 // expected-error@-1{{parentheses are required around this expression in a requires clause}}
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}}
101 template<typename T
> requires (foo
<T
>())
104 template<typename T
> requires T
{}
105 // expected-error@-1{{parentheses are required around this expression in a requires clause}}
108 template<typename T
> requires
sizeof(T
) == 0
109 // expected-error@-1{{parentheses are required around this expression in a requires clause}}
112 template<typename T
> requires (sizeof(T
)) == 0
113 // expected-error@-1{{parentheses are required around this expression in a requires clause}}
116 template<typename T
> requires
0
117 // expected-error@-1{{atomic constraint must be of type 'bool' (found 'int')}}
120 template<typename T
> requires foo
<T
>
122 // expected-error@-1{{expected '(' for function-style cast or type construction}}
125 void bar() requires foo
<T
>();
126 // expected-error@-1{{parentheses are required around this expression in a requires clause}}
129 void bar() requires (foo
<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}}
137 void bar() requires T
{};
138 // expected-error@-1{{parentheses are required around this expression in a requires clause}}
141 void bar() requires
sizeof(T
) == 0;
142 // expected-error@-1{{parentheses are required around this expression in a requires clause}}
145 void bar() requires (sizeof(T
)) == 0;
146 // expected-error@-1{{parentheses are required around this expression in a requires clause}}
149 void bar(int x
, int y
) requires (x
, y
, true);
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}}
161 auto lambda1
= [] (auto x
) requires (sizeof(decltype(x
)) == 1) { };
163 auto lambda2
= [] (auto x
) constexpr -> int requires (sizeof(decltype(x
)) == 1) { return 0; };
165 auto lambda3
= []<auto> requires(sizeof(char) == 1){};
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}}
174 template <typename T
> T Foo
;
176 template <typename T
> auto C(Foo
<T
>);
178 template <typename T
> struct D
{
179 decltype(T()(C
<T
>)) Type
;
182 template <typename T
, typename U
> D
<T
> G(T
, U
) { return {}; }
188 // ~~~~~~~~~~ T: Depth: 0, Index: 0
189 requires requires
{ [](auto...) {}; }(T
)
190 // ~~~~ auto: Depth: 1, Index: 0
195 int a
= []<int=0> requires requires
{ [](auto){}; } { return 0; }();
197 } // namespace GH78524
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 ()'}}