1 // RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks %s -fcxx-exceptions
2 // RUN: %clang_cc1 -std=c++20 -verify -fsyntax-only -fblocks %s -fcxx-exceptions
3 // RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -fcxx-exceptions
4 // RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -fblocks %s -DCPP14_AND_EARLIER -fcxx-exceptions
7 namespace test_lambda_is_literal
{
8 #ifdef CPP14_AND_EARLIER
9 //expected-error@+4{{not a literal type}}
10 //expected-note@+2{{lambda closure types are non-literal types before C++17}}
13 constexpr int foo(decltype(L
) l
) { return 0; }
17 #ifndef CPP14_AND_EARLIER
18 namespace test_constexpr_checking
{
21 struct NonLit
{ ~NonLit(); }; //expected-note{{not literal}}
22 auto L
= [](NonLit NL
) constexpr { }; //expected-error{{not a literal type}}
26 auto L
= [](int I
) constexpr { if (I
== 5) asm("non-constexpr"); };
27 #if __cpp_constexpr < 201907L
28 //expected-warning@-2{{use of this statement in a constexpr function is a C++20 extension}}
32 // This is not constexpr until C++20, as the requirements on constexpr
33 // functions don't permit try-catch blocks.
34 #if __cplusplus <= 201703L
35 // expected-error@#try-catch {{constant expression}}
36 // expected-note@#try-catch {{non-constexpr function 'operator()'}}
37 // expected-note@#try-catch {{declared here}}
39 constexpr int try_catch
= [] { // #try-catch
40 try { return 0; } catch (...) { return 1; }
43 // These lambdas have constexpr operator() even though they can never produce a
44 // constant expression.
45 auto never_constant_1
= [] { // expected-note {{here}}
49 auto never_constant_2
= [] () -> int { // expected-note {{here}}
51 struct test_never_constant
{
52 #if __cplusplus >= 201703L
53 // expected-error@+3 {{non-constexpr declaration of 'operator()' follows constexpr declaration}}
54 // expected-error@+3 {{non-constexpr declaration of 'operator()' follows constexpr declaration}}
56 friend auto decltype(never_constant_1
)::operator()() const;
57 friend int decltype(never_constant_2
)::operator()() const;
60 } // end ns test_constexpr_checking
62 namespace test_constexpr_call
{
65 auto L
= [](int I
) { return I
; };
66 static_assert(L(3) == 3);
69 auto L
= [](auto a
) { return a
; };
70 static_assert(L(3) == 3);
71 static_assert(L(3.14) == 3.14);
74 auto L
= [](auto a
) { asm("non-constexpr"); return a
; };
75 constexpr int I
= //expected-error{{must be initialized by a constant expression}}
77 #if __cpp_constexpr < 201907L
78 //expected-note@-2{{non-constexpr function}}
79 //expected-note@-5{{declared here}}
81 //expected-note@-7{{subexpression not valid in a constant expression}}
82 //expected-note@-6{{in call to}}
86 } // end ns test_constexpr_call
88 namespace test_captureless_lambda
{
91 auto L
= [] { return c
; };
92 constexpr char C
= L();
95 void f(char c
) { //expected-note{{declared here}}
96 auto L
= [] { return c
; }; //expected-error{{cannot be implicitly captured}} expected-note{{lambda expression begins here}} expected-note 2 {{capture 'c' by}} expected-note 2 {{default capture by}}
102 namespace test_conversion_function_for_non_capturing_lambdas
{
105 auto L
= [](int i
) { return i
; };
106 constexpr int (*fpi
)(int) = L
;
107 static_assert(fpi(3) == 3);
108 auto GL
= [](auto a
) { return a
; };
110 constexpr char (*fp2
)(char) = GL
;
111 constexpr double (*fp3
)(double) = GL
;
112 constexpr const char* (*fp4
)(const char*) = GL
;
113 static_assert(fp2('3') == '3');
114 static_assert(fp3(3.14) == 3.14);
115 constexpr const char *Str
= "abc";
116 static_assert(fp4(Str
) == Str
);
118 auto NCL
= [](int i
) { static int j
; return j
; }; //expected-note{{declared here}}
119 constexpr int (*fp5
)(int) = NCL
;
120 constexpr int I
= //expected-error{{must be initialized by a constant expression}}
121 fp5(5); //expected-note{{non-constexpr function}}
123 namespace test_dont_always_instantiate_constexpr_templates
{
125 auto explicit_return_type
= [](auto x
) -> int { return x
.get(); };
126 decltype(explicit_return_type(0)) c
; // OK
128 auto deduced_return_type
= [](auto x
) { return x
.get(); }; //expected-error{{not a structure or union}}
129 decltype(deduced_return_type(0)) d
; //expected-note{{requested here}}
133 } // end ns test_dont_always_instantiate_constexpr_templates
136 } // end ns test_conversion_function_for_non_capturing_lambdas
138 namespace test_lambda_is_cce
{
139 namespace ns1_simple_lambda
{
142 constexpr int I
= [](auto a
) { return a
; }(10);
144 static_assert(I
== 10);
145 static_assert(10 == [](auto a
) { return a
; }(10));
146 static_assert(3.14 == [](auto a
) { return a
; }(3.14));
151 constexpr auto f(int i
) {
153 auto L
= [=](auto a
) {
155 return sizeof(i
) + sizeof(a
) + sizeof(d
);
157 int I
= L("abc") + L(nullptr);
160 constexpr auto L
= f(3);
161 constexpr auto M
= L("abc") + L(nullptr);
163 static_assert(M
== sizeof(int) * 2 + sizeof(double) * 2 + sizeof(nullptr) + sizeof(const char*));
168 constexpr auto f(int i
) {
169 auto L
= [](auto a
) { return a
+ a
; };
172 constexpr auto L
= f(3);
173 constexpr int I
= L(6);
174 static_assert(I
== 12);
177 namespace contained_lambdas_call_operator_is_not_constexpr
{
178 constexpr auto f(int i
) {
180 auto L
= [=](auto a
) {
183 return sizeof(i
) + sizeof(a
) + sizeof(d
);
188 constexpr auto L
= f(3);
190 constexpr auto M
= // expected-error{{must be initialized by}}
192 #if __cpp_constexpr < 201907L
193 //expected-note@-2{{non-constexpr function}}
194 //expected-note@-14{{declared here}}
196 //expected-note@-14{{subexpression not valid in a constant expression}}
197 //expected-note@-6{{in call to}}
199 } // end ns contained_lambdas_call_operator_is_not_constexpr
203 } // end ns1_simple_lambda
205 namespace test_captures_1
{
207 constexpr auto f(int i
) {
208 struct S
{ int x
; } s
= { i
* 2 };
209 auto L
= [=](auto a
) {
214 constexpr auto M
= f(3);
216 static_assert(M(10) == 19);
218 } // end test_captures_1::ns1
222 constexpr auto foo(int n
) {
223 auto L
= [i
= n
] (auto N
) mutable {
224 if (!N(i
)) throw "error";
229 auto M
= L([n
](int p
) { return p
== n
; });
231 L([n
](int p
) { return p
== n
+ 2; });
236 constexpr auto L
= foo(3);
238 } // end test_captures_1::ns2
241 constexpr auto foo(int n
) {
242 auto L
= [i
= n
] (auto N
) mutable {
243 if (!N(i
)) throw "error";
245 return [i
]() mutable {
250 auto M
= L([n
](int p
) { return p
== n
; });
252 L([n
](int p
) { return p
== n
; });
257 constexpr auto L
= foo(3);
258 } // end test_captures_1::ns3
260 namespace ns2_capture_this_byval
{
263 constexpr S(int s
) : s
{s
} { }
264 constexpr auto f(S o
) {
265 return [*this,o
] (auto a
) { return s
+ o
.s
+ a
.s
; };
269 constexpr auto L
= S
{5}.f(S
{10});
270 static_assert(L(S
{100}) == 115);
271 } // end test_captures_1::ns2_capture_this_byval
273 namespace ns2_capture_this_byref
{
277 constexpr S(int s
) : s
{s
} { }
278 constexpr auto f() const {
279 return [this] { return s
; };
284 constexpr auto L
= SObj
.f();
285 constexpr int I
= L();
286 static_assert(I
== 5);
288 } // end ns2_capture_this_byref
290 } // end test_captures_1
292 namespace test_capture_array
{
294 constexpr auto f(int I
) {
295 int arr
[] = { I
, I
*2, I
* 3 };
296 auto L1
= [&] (auto a
) { return arr
[a
]; };
298 struct X
{ int x
, y
; };
299 return [=](auto a
) { return X
{arr
[a
],r
}; };
301 constexpr auto L
= f(3);
302 static_assert(L(0).x
== 3);
303 static_assert(L(0).y
== 9);
304 static_assert(L(1).x
== 6);
305 static_assert(L(1).y
== 9);
308 } // end test_capture_array
309 namespace ns1_test_lvalue_type
{
312 constexpr bool B
= [&]{ return &n
; }() == &n
; // should be accepted
314 } // end ns1_unimplemented
316 } // end ns test_lambda_is_cce
321 return [=]() constexpr { return Capture
; }();
324 static_assert(fn() == 42, "");
327 constexpr int tfn() {
329 return [=]() constexpr { return Capture
; }();
332 static_assert(tfn
<int>() == 42, "");
334 constexpr int gfn() {
336 return [=](auto P
) constexpr { return Capture
+ P
; }(58);
339 static_assert(gfn() == 100, "");
341 constexpr bool OtherCaptures() {
343 constexpr auto Outer
= [](auto P
) constexpr { return 42 + P
; };
344 auto Inner
= [&](auto O
) constexpr { return O(58) + Capture
; };
345 return Inner(Outer
) == 142;
348 static_assert(OtherCaptures(), "");
349 } // namespace PR36054
351 #endif // ndef CPP14_AND_EARLIER