Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / SemaCXX / lambda-unevaluated.cpp
blob10d4c2228ec9be769a2a9cd58c4fbaaa05d5e464
1 // RUN: %clang_cc1 -std=c++20 %s -Wno-c++23-extensions -verify
2 // RUN: %clang_cc1 -std=c++23 %s -verify
5 template <auto> struct Nothing {};
6 Nothing<[]() { return 0; }()> nothing;
8 template <typename> struct NothingT {};
9 Nothing<[]() { return 0; }> nothingT;
11 template <typename T>
12 concept True = [] { return true; }();
13 static_assert(True<int>);
15 static_assert(sizeof([] { return 0; }));
16 static_assert(sizeof([] { return 0; }()));
18 void f() noexcept(noexcept([] { return 0; }()));
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; }));
25 template <auto T>
26 int unique_test1();
27 static_assert(&unique_test1<[](){}> != &unique_test1<[](){}>);
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}}
37 template <typename T>
38 auto foo(decltype([] {
39 return [] { return T(); }();
40 })) {}
42 void test() {
43 foo<int>({});
46 template <typename T>
47 struct C {
48 template <typename U>
49 auto foo(decltype([] {
50 return [] { return T(); }();
51 })) {}
54 void test2() {
55 C<int>{}.foo<long>({});
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}}
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}}
70 namespace GH51416 {
72 template <class T>
73 struct A {
74 void spam(decltype([] {}));
77 template <class T>
78 void A<T>::spam(decltype([] {})) // expected-error{{out-of-line definition of 'spam' does not match}}
81 struct B {
82 template <class T>
83 void spam(decltype([] {}));
86 template <class T>
87 void B::spam(decltype([] {})) {} // expected-error{{out-of-line definition of 'spam' does not match}}
89 } // namespace GH51416
91 namespace GH50376 {
93 template <typename T, typename Fn>
94 struct foo_t { // expected-note 2{{candidate constructor}}
95 foo_t(T ptr) {} // expected-note{{candidate constructor}}
98 template <typename T>
99 using alias = foo_t<T, decltype([](int) { return 0; })>;
101 template <typename T>
102 auto fun(T const &t) -> alias<T> {
103 return alias<T>{t}; // expected-error{{no viable conversion from returned value of type 'alias<...>'}}
106 void f() {
107 int i;
108 auto const error = fun(i); // expected-note{{in instantiation}}
111 } // namespace GH50376
113 namespace GH51414 {
114 template <class T> void spam(decltype([] {}) (*s)[sizeof(T)] = nullptr) {}
115 void foo() {
116 spam<int>();
118 } // namespace GH51414
120 namespace GH51641 {
121 template <class T>
122 void foo(decltype(+[](T) {}) lambda, T param);
123 static_assert(!__is_same(decltype(foo<int>), void));
124 } // namespace GH51641
126 namespace StaticLambdas {
127 template <auto> struct Nothing {};
128 Nothing<[]() static { return 0; }()> nothing;
130 template <typename> struct NothingT {};
131 Nothing<[]() static { return 0; }> nothingT;
133 template <typename T>
134 concept True = [] static { return true; }();
135 static_assert(True<int>);
137 static_assert(sizeof([] static { return 0; }));
138 static_assert(sizeof([] static { return 0; }()));
140 void f() noexcept(noexcept([] static { return 0; }()));
142 using a = decltype([] static { return 0; });
143 using b = decltype([] static { return 0; }());
144 using c = decltype([]() static noexcept(noexcept([] { return 0; }())) { return 0; });
145 using d = decltype(sizeof([] static { return 0; }));
149 namespace lambda_in_trailing_decltype {
150 auto x = ([](auto) -> decltype([] {}()) {}(0), 2);
153 namespace lambda_in_constraints {
154 struct WithFoo { static void foo(); };
156 template <class T>
157 concept lambda_works = requires {
158 []() { T::foo(); }; // expected-error{{type 'int' cannot be used prior to '::'}}
159 // expected-note@-1{{while substituting into a lambda expression here}}
160 // expected-note@-2{{in instantiation of requirement here}}
161 // expected-note@-4{{while substituting template arguments into constraint expression here}}
164 static_assert(!lambda_works<int>); // expected-note {{while checking the satisfaction of concept 'lambda_works<int>' requested here}}
165 static_assert(lambda_works<WithFoo>);
167 template <class T>
168 int* func(T) requires requires { []() { T::foo(); }; }; // expected-error{{type 'int' cannot be used prior to '::'}}
169 // expected-note@-1{{while substituting into a lambda expression here}}
170 // expected-note@-2{{in instantiation of requirement here}}
171 // expected-note@-3{{while substituting template arguments into constraint expression here}}
172 double* func(...);
174 static_assert(__is_same(decltype(func(0)), double*)); // expected-note {{while checking constraint satisfaction for template 'func<int>' required here}}
175 // expected-note@-1 {{in instantiation of function template specialization 'lambda_in_constraints::func<int>'}}
176 static_assert(__is_same(decltype(func(WithFoo())), int*));
178 template <class T>
179 auto direct_lambda(T) -> decltype([] { T::foo(); }) {}
180 void direct_lambda(...) {}
182 void recursive() {
183 direct_lambda(0); // expected-error@-4 {{type 'int' cannot be used prior to '::'}}
184 // expected-note@-1 {{while substituting deduced template arguments}}
185 // expected-note@-6 {{while substituting into a lambda}}
186 bool x = requires { direct_lambda(0); }; // expected-error@-7 {{type 'int' cannot be used prior to '::'}}
187 // expected-note@-1 {{while substituting deduced template arguments}}
188 // expected-note@-9 {{while substituting into a lambda}}