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()6 void 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()29 void 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()42 void 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()73 void 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()87 int 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)113 template<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()130 void 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}}