xref: /llvm-project/clang/test/SemaCXX/lambda-unevaluated.cpp (revision 3972ed57088f6515b787d7d38dec03dc74e51827)
1 // RUN: %clang_cc1 -std=c++20 %s -Wno-c++23-extensions -verify
2 // RUN: %clang_cc1 -std=c++23 %s -verify
3 
4 
5 template <auto> struct Nothing {};
6 Nothing<[]() { return 0; }()> nothing;
7 
8 template <typename> struct NothingT {};
9 Nothing<[]() { return 0; }> nothingT;
10 
11 template <typename T>
12 concept True = [] { return true; }();
13 static_assert(True<int>);
14 
15 static_assert(sizeof([] { return 0; }));
16 static_assert(sizeof([] { return 0; }()));
17 
18 void f()  noexcept(noexcept([] { return 0; }()));
19 
20 using a = decltype([] { return 0; });
21 using b = decltype([] { return 0; }());
22 using c = decltype([]() noexcept(noexcept([] { return 0; }())) { return 0; });
23 using d = decltype(sizeof([] { return 0; }));
24 
25 template <auto T>
26 int unique_test1();
27 static_assert(&unique_test1<[](){}> != &unique_test1<[](){}>);
28 
29 template <class T>
30 auto g(T) -> decltype([]() { T::invalid; } ());
31 auto e = g(0); // expected-error@-1{{type 'int' cannot be used prior to '::'}}
32                // expected-note@-1{{while substituting deduced template}}
33                // expected-note@-3{{while substituting into a lambda}}
34                // expected-error@-3 {{no matching function for call to 'g'}}
35                // expected-note@-5 {{substitution failure}}
36 
37 template <typename T>
38 auto foo(decltype([] {
39   return [] { return T(); }();
40 })) {}
41 
42 void test() {
43   foo<int>({});
44 }
45 
46 template <typename T>
47 struct C {
48   template <typename U>
49   auto foo(decltype([] {
50     return [] { return T(); }();
51   })) {}
52 };
53 
54 void test2() {
55   C<int>{}.foo<long>({});
56 }
57 
58 namespace PR52073 {
59 // OK, these are distinct functions not redefinitions.
60 template<typename> void f(decltype([]{})) {} // expected-note {{candidate}}
61 template<typename> void f(decltype([]{})) {} // expected-note {{candidate}}
62 void use_f() { f<int>({}); } // expected-error {{ambiguous}}
63 
64 // Same.
65 template<int N> void g(const char (*)[([]{ return N; })()]) {} // expected-note {{candidate}}
66 template<int N> void g(const char (*)[([]{ return N; })()]) {} // expected-note {{candidate}}
67 void use_g() { g<6>(&"hello"); } // expected-error {{ambiguous}}
68 }
69 
70 namespace GH51416 {
71 
72 template <class T>
73 struct A { // #defined-here-A
74   void spam(decltype([] {}));
75 };
76 
77 template <class T>
78 void A<T>::spam(decltype([] {})) // expected-error{{out-of-line definition of 'spam' does not match}}
79                                  // expected-note@#defined-here-A{{defined here}}
80 {}
81 
82 struct B { // #defined-here-B
83   template <class T>
84   void spam(decltype([] {}));
85 };
86 
87 template <class T>
88 void B::spam(decltype([] {})) {} // expected-error{{out-of-line definition of 'spam' does not match}}
89                                  // expected-note@#defined-here-B{{defined here}}
90 
91 } // namespace GH51416
92 
93 namespace GH50376 {
94 
95 template <typename T, typename Fn>
96 struct foo_t {    // expected-note 2{{candidate constructor}}
97   foo_t(T ptr) {} // expected-note{{candidate constructor}}
98 };
99 
100 template <typename T>
101 using alias = foo_t<T, decltype([](int) { return 0; })>;
102 
103 template <typename T>
104 auto fun(T const &t) -> alias<T> {
105   return alias<T>{t}; // expected-error{{no viable conversion from returned value of type 'alias<...>'}}
106 }
107 
108 void f() {
109   int i;
110   auto const error = fun(i); // expected-note{{in instantiation}}
111 }
112 
113 } // namespace GH50376
114 
115 namespace GH51414 {
116 template <class T> void spam(decltype([] {}) (*s)[sizeof(T)] = nullptr) {}
117 void foo() {
118   spam<int>();
119 }
120 } // namespace GH51414
121 
122 namespace GH51641 {
123 template <class T>
124 void foo(decltype(+[](T) {}) lambda, T param);
125 static_assert(!__is_same(decltype(foo<int>), void));
126 } // namespace GH51641
127 
128 namespace StaticLambdas {
129 template <auto> struct Nothing {};
130 Nothing<[]() static { return 0; }()> nothing;
131 
132 template <typename> struct NothingT {};
133 Nothing<[]() static { return 0; }> nothingT;
134 
135 template <typename T>
136 concept True = [] static { return true; }();
137 static_assert(True<int>);
138 
139 static_assert(sizeof([] static { return 0; }));
140 static_assert(sizeof([] static { return 0; }()));
141 
142 void f()  noexcept(noexcept([] static { return 0; }()));
143 
144 using a = decltype([] static { return 0; });
145 using b = decltype([] static { return 0; }());
146 using c = decltype([]() static noexcept(noexcept([] { return 0; }())) { return 0; });
147 using d = decltype(sizeof([] static { return 0; }));
148 
149 }
150 
151 namespace lambda_in_trailing_decltype {
152 auto x = ([](auto) -> decltype([] {}()) {}(0), 2);
153 }
154 
155 namespace lambda_in_constraints {
156 struct WithFoo { static void foo(); };
157 
158 template <class T>
159 concept lambda_works = requires {
160     []() { T::foo(); }; // expected-error{{type 'int' cannot be used prior to '::'}}
161                         // expected-note@-1{{while substituting into a lambda expression here}}
162                         // expected-note@-2{{in instantiation of requirement here}}
163                         // expected-note@-4{{while substituting template arguments into constraint expression here}}
164 };
165 
166 static_assert(!lambda_works<int>); // expected-note {{while checking the satisfaction of concept 'lambda_works<int>' requested here}}
167 static_assert(lambda_works<WithFoo>);
168 
169 template <class T>
170 int* func(T) requires requires { []() { T::foo(); }; }; // expected-error{{type 'int' cannot be used prior to '::'}}
171                                                         // expected-note@-1{{while substituting into a lambda expression here}}
172                                                         // expected-note@-2{{in instantiation of requirement here}}
173                                                         // expected-note@-3{{while substituting template arguments into constraint expression here}}
174 double* func(...);
175 
176 static_assert(__is_same(decltype(func(0)), double*)); // expected-note {{while checking constraint satisfaction for template 'func<int>' required here}}
177                                                       // expected-note@-1 {{in instantiation of function template specialization 'lambda_in_constraints::func<int>'}}
178 static_assert(__is_same(decltype(func(WithFoo())), int*));
179 
180 template <class T>
181 auto direct_lambda(T) -> decltype([] { T::foo(); }) {}
182 void direct_lambda(...) {}
183 
184 void recursive() {
185     direct_lambda(0); // expected-error@-4 {{type 'int' cannot be used prior to '::'}}
186                       // expected-note@-1 {{while substituting deduced template arguments}}
187                       // expected-note@-6 {{while substituting into a lambda}}
188     bool x = requires { direct_lambda(0); }; // expected-error@-7 {{type 'int' cannot be used prior to '::'}}
189                                              // expected-note@-1 {{while substituting deduced template arguments}}
190                                              // expected-note@-9 {{while substituting into a lambda}}
191 
192 }
193 }
194 
195 // GH63845: Test if we have skipped past RequiresExprBodyDecls in tryCaptureVariable().
196 namespace GH63845 {
197 
198 template <bool> struct A {};
199 
200 struct true_type {
201   constexpr operator bool() noexcept { return true; }
202 };
203 
204 constexpr bool foo() {
205   true_type x{};
206   return requires { typename A<x>; };
207 }
208 
209 static_assert(foo());
210 
211 } // namespace GH63845
212 
213 // GH69307: Test if we can correctly handle param decls that have yet to get into the function scope.
214 namespace GH69307 {
215 
216 constexpr auto ICE() {
217   constexpr auto b = 1;
218   return [=](auto c) -> int
219            requires requires { b + c; }
220   { return 1; };
221 };
222 
223 constexpr auto Ret = ICE()(1);
224 
225 } // namespace GH69307
226 
227 // GH88081: Test if we evaluate the requires expression with lambda captures properly.
228 namespace GH88081 {
229 
230 // Test that ActOnLambdaClosureQualifiers() is called only once.
231 void foo(auto value)
232   requires requires { [&] -> decltype(value) {}; }
233   // expected-error@-1 {{non-local lambda expression cannot have a capture-default}}
234 {}
235 
236 struct S { //#S
237   S(auto value) //#S-ctor
238   requires requires { [&] -> decltype(value) { return 2; }; } {} // #S-requires
239 
240   static auto foo(auto value) -> decltype([&]() -> decltype(value) {}()) { return {}; } // #S-foo
241 
242   // FIXME: 'value' does not constitute an ODR use here. Add a diagnostic for it.
243   static auto bar(auto value) -> decltype([&] { return value; }()) {
244     return "a"; // #bar-body
245   }
246 };
247 
248 S s("a"); // #use
249 // expected-error@#S-requires {{cannot initialize return object of type 'decltype(value)' (aka 'const char *') with an rvalue of type 'int'}}
250 // expected-error@#use {{no matching constructor}}
251 // expected-note@#S-requires {{substituting into a lambda expression here}}
252 // expected-note@#S-requires {{substituting template arguments into constraint expression here}}
253 // expected-note@#S-requires {{in instantiation of requirement here}}
254 // expected-note@#use {{checking constraint satisfaction for template 'S<const char *>' required here}}
255 // expected-note@#use {{requested here}}
256 // expected-note-re@#S 2{{candidate constructor {{.*}} not viable}}
257 // expected-note@#S-ctor {{constraints not satisfied}}
258 // expected-note-re@#S-requires {{because {{.*}} would be invalid}}
259 
260 void func() {
261   S::foo(42);
262   S::bar("str");
263   S::bar(0.618);
264   // expected-error-re@#bar-body {{cannot initialize return object of type {{.*}} (aka 'double') with an lvalue of type 'const char[2]'}}
265   // expected-note@-2 {{requested here}}
266 }
267 
268 } // namespace GH88081
269