1*67e74705SXin Li // RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -emit-llvm-only %s
2*67e74705SXin Li // DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING
3*67e74705SXin Li // DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fms-extensions %s -DMS_EXTENSIONS
4*67e74705SXin Li // DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING
5*67e74705SXin Li
6*67e74705SXin Li constexpr int ODRUSE_SZ = sizeof(char);
7*67e74705SXin Li
8*67e74705SXin Li template<class T, int N>
f(T,const int (&)[N])9*67e74705SXin Li void f(T, const int (&)[N]) { }
10*67e74705SXin Li
11*67e74705SXin Li template<class T>
f(const T &,const int (&)[ODRUSE_SZ])12*67e74705SXin Li void f(const T&, const int (&)[ODRUSE_SZ]) { }
13*67e74705SXin Li
14*67e74705SXin Li #define DEFINE_SELECTOR(x) \
15*67e74705SXin Li int selector_ ## x[sizeof(x) == ODRUSE_SZ ? ODRUSE_SZ : ODRUSE_SZ + 5]
16*67e74705SXin Li
17*67e74705SXin Li #define F_CALL(x, a) f(x, selector_ ## a)
18*67e74705SXin Li
19*67e74705SXin Li // This is a risky assumption, because if an empty class gets captured by value
20*67e74705SXin Li // the lambda's size will still be '1'
21*67e74705SXin Li #define ASSERT_NO_CAPTURES(L) static_assert(sizeof(L) == 1, "size of closure with no captures must be 1")
22*67e74705SXin Li #define ASSERT_CLOSURE_SIZE_EXACT(L, N) static_assert(sizeof(L) == (N), "size of closure must be " #N)
23*67e74705SXin Li #define ASSERT_CLOSURE_SIZE(L, N) static_assert(sizeof(L) >= (N), "size of closure must be >=" #N)
24*67e74705SXin Li
25*67e74705SXin Li
26*67e74705SXin Li namespace sample {
27*67e74705SXin Li struct X {
28*67e74705SXin Li int i;
Xsample::X29*67e74705SXin Li X(int i) : i(i) { }
30*67e74705SXin Li };
31*67e74705SXin Li }
32*67e74705SXin Li
33*67e74705SXin Li namespace test_transformations_in_templates {
foo(T t)34*67e74705SXin Li template<class T> void foo(T t) {
35*67e74705SXin Li auto L = [](auto a) { return a; };
36*67e74705SXin Li }
foo2(T t)37*67e74705SXin Li template<class T> void foo2(T t) {
38*67e74705SXin Li auto L = [](auto a) -> void {
39*67e74705SXin Li auto M = [](char b) -> void {
40*67e74705SXin Li auto N = [](auto c) -> void {
41*67e74705SXin Li int selector[sizeof(c) == 1 ?
42*67e74705SXin Li (sizeof(b) == 1 ? 1 : 2)
43*67e74705SXin Li : 2
44*67e74705SXin Li ]{};
45*67e74705SXin Li };
46*67e74705SXin Li N('a');
47*67e74705SXin Li };
48*67e74705SXin Li };
49*67e74705SXin Li L(3.14);
50*67e74705SXin Li }
51*67e74705SXin Li
doit()52*67e74705SXin Li void doit() {
53*67e74705SXin Li foo(3);
54*67e74705SXin Li foo('a');
55*67e74705SXin Li foo2('A');
56*67e74705SXin Li }
57*67e74705SXin Li }
58*67e74705SXin Li
59*67e74705SXin Li namespace test_return_type_deduction {
60*67e74705SXin Li
doit()61*67e74705SXin Li void doit() {
62*67e74705SXin Li
63*67e74705SXin Li auto L = [](auto a, auto b) {
64*67e74705SXin Li if ( a > b ) return a;
65*67e74705SXin Li return b;
66*67e74705SXin Li };
67*67e74705SXin Li L(2, 4);
68*67e74705SXin Li {
69*67e74705SXin Li auto L2 = [](auto a, int i) {
70*67e74705SXin Li return a + i;
71*67e74705SXin Li };
72*67e74705SXin Li L2(3.14, 2);
73*67e74705SXin Li }
74*67e74705SXin Li {
75*67e74705SXin Li int a; //expected-note{{declared here}}
76*67e74705SXin Li auto B = []() { return ^{ return a; }; }; //expected-error{{cannot be implicitly capture}}\
77*67e74705SXin Li //expected-note{{begins here}}
78*67e74705SXin Li //[](){ return ({int b = 5; return 'c'; 'x';}); };
79*67e74705SXin Li
80*67e74705SXin Li //auto X = ^{ return a; };
81*67e74705SXin Li
82*67e74705SXin Li //auto Y = []() -> auto { return 3; return 'c'; };
83*67e74705SXin Li
84*67e74705SXin Li }
85*67e74705SXin Li }
86*67e74705SXin Li }
87*67e74705SXin Li
88*67e74705SXin Li
89*67e74705SXin Li namespace test_no_capture{
doit()90*67e74705SXin Li void doit() {
91*67e74705SXin Li const int x = 10; //expected-note{{declared here}}
92*67e74705SXin Li {
93*67e74705SXin Li // should not capture 'x' - variable undergoes lvalue-to-rvalue
94*67e74705SXin Li auto L = [=](auto a) {
95*67e74705SXin Li int y = x;
96*67e74705SXin Li return a + y;
97*67e74705SXin Li };
98*67e74705SXin Li ASSERT_NO_CAPTURES(L);
99*67e74705SXin Li }
100*67e74705SXin Li {
101*67e74705SXin Li // should not capture 'x' - even though certain instantiations require
102*67e74705SXin Li auto L = [](auto a) { //expected-note{{begins here}}
103*67e74705SXin Li DEFINE_SELECTOR(a);
104*67e74705SXin Li F_CALL(x, a); //expected-error{{'x' cannot be implicitly captured}}
105*67e74705SXin Li };
106*67e74705SXin Li ASSERT_NO_CAPTURES(L);
107*67e74705SXin Li L('s'); //expected-note{{in instantiation of}}
108*67e74705SXin Li }
109*67e74705SXin Li {
110*67e74705SXin Li // Does not capture because no default capture in inner most lambda 'b'
111*67e74705SXin Li auto L = [=](auto a) {
112*67e74705SXin Li return [=](int p) {
113*67e74705SXin Li return [](auto b) {
114*67e74705SXin Li DEFINE_SELECTOR(a);
115*67e74705SXin Li F_CALL(x, a);
116*67e74705SXin Li return 0;
117*67e74705SXin Li };
118*67e74705SXin Li };
119*67e74705SXin Li };
120*67e74705SXin Li ASSERT_NO_CAPTURES(L);
121*67e74705SXin Li }
122*67e74705SXin Li } // doit
123*67e74705SXin Li } // namespace
124*67e74705SXin Li
125*67e74705SXin Li namespace test_capture_of_potentially_evaluated_expression {
doit()126*67e74705SXin Li void doit() {
127*67e74705SXin Li const int x = 5;
128*67e74705SXin Li {
129*67e74705SXin Li auto L = [=](auto a) {
130*67e74705SXin Li DEFINE_SELECTOR(a);
131*67e74705SXin Li F_CALL(x, a);
132*67e74705SXin Li };
133*67e74705SXin Li static_assert(sizeof(L) == 4, "Must be captured");
134*67e74705SXin Li }
135*67e74705SXin Li {
136*67e74705SXin Li int j = 0; //expected-note{{declared}}
137*67e74705SXin Li auto L = [](auto a) { //expected-note{{begins here}}
138*67e74705SXin Li return j + 1; //expected-error{{cannot be implicitly captured}}
139*67e74705SXin Li };
140*67e74705SXin Li }
141*67e74705SXin Li {
142*67e74705SXin Li const int x = 10;
143*67e74705SXin Li auto L = [](auto a) {
144*67e74705SXin Li //const int y = 20;
145*67e74705SXin Li return [](int p) {
146*67e74705SXin Li return [](auto b) {
147*67e74705SXin Li DEFINE_SELECTOR(a);
148*67e74705SXin Li F_CALL(x, a);
149*67e74705SXin Li return 0;
150*67e74705SXin Li };
151*67e74705SXin Li };
152*67e74705SXin Li };
153*67e74705SXin Li auto M = L(3);
154*67e74705SXin Li auto N = M(5);
155*67e74705SXin Li
156*67e74705SXin Li }
157*67e74705SXin Li
158*67e74705SXin Li { // if the nested capture does not implicitly or explicitly allow any captures
159*67e74705SXin Li // nothing should capture - and instantiations will create errors if needed.
160*67e74705SXin Li const int x = 0;
161*67e74705SXin Li auto L = [=](auto a) { // <-- #A
162*67e74705SXin Li const int y = 0;
163*67e74705SXin Li return [](auto b) { // <-- #B
164*67e74705SXin Li int c[sizeof(b)];
165*67e74705SXin Li f(x, c);
166*67e74705SXin Li f(y, c);
167*67e74705SXin Li int i = x;
168*67e74705SXin Li };
169*67e74705SXin Li };
170*67e74705SXin Li ASSERT_NO_CAPTURES(L);
171*67e74705SXin Li auto M_int = L(2);
172*67e74705SXin Li ASSERT_NO_CAPTURES(M_int);
173*67e74705SXin Li }
174*67e74705SXin Li { // Permutations of this example must be thoroughly tested!
175*67e74705SXin Li const int x = 0;
176*67e74705SXin Li sample::X cx{5};
177*67e74705SXin Li auto L = [=](auto a) {
178*67e74705SXin Li const int z = 3;
179*67e74705SXin Li return [&,a](auto b) {
180*67e74705SXin Li const int y = 5;
181*67e74705SXin Li return [=](auto c) {
182*67e74705SXin Li int d[sizeof(a) == sizeof(c) || sizeof(c) == sizeof(b) ? 2 : 1];
183*67e74705SXin Li f(x, d);
184*67e74705SXin Li f(y, d);
185*67e74705SXin Li f(z, d);
186*67e74705SXin Li decltype(a) A = a;
187*67e74705SXin Li decltype(b) B = b;
188*67e74705SXin Li const int &i = cx.i;
189*67e74705SXin Li };
190*67e74705SXin Li };
191*67e74705SXin Li };
192*67e74705SXin Li auto M = L(3)(3.5);
193*67e74705SXin Li M(3.14);
194*67e74705SXin Li }
195*67e74705SXin Li }
196*67e74705SXin Li namespace Test_no_capture_of_clearly_no_odr_use {
foo()197*67e74705SXin Li auto foo() {
198*67e74705SXin Li const int x = 10;
199*67e74705SXin Li auto L = [=](auto a) {
200*67e74705SXin Li return [=](auto b) {
201*67e74705SXin Li return [=](auto c) {
202*67e74705SXin Li int A = x;
203*67e74705SXin Li return A;
204*67e74705SXin Li };
205*67e74705SXin Li };
206*67e74705SXin Li };
207*67e74705SXin Li auto M = L(1);
208*67e74705SXin Li auto N = M(2.14);
209*67e74705SXin Li ASSERT_NO_CAPTURES(L);
210*67e74705SXin Li ASSERT_NO_CAPTURES(N);
211*67e74705SXin Li
212*67e74705SXin Li return 0;
213*67e74705SXin Li }
214*67e74705SXin Li }
215*67e74705SXin Li
216*67e74705SXin Li namespace Test_capture_of_odr_use_var {
foo()217*67e74705SXin Li auto foo() {
218*67e74705SXin Li const int x = 10;
219*67e74705SXin Li auto L = [=](auto a) {
220*67e74705SXin Li return [=](auto b) {
221*67e74705SXin Li return [=](auto c) {
222*67e74705SXin Li int A = x;
223*67e74705SXin Li const int &i = x;
224*67e74705SXin Li decltype(a) A2 = a;
225*67e74705SXin Li return A;
226*67e74705SXin Li };
227*67e74705SXin Li };
228*67e74705SXin Li };
229*67e74705SXin Li auto M_int = L(1);
230*67e74705SXin Li auto N_int_int = M_int(2);
231*67e74705SXin Li ASSERT_CLOSURE_SIZE_EXACT(L, sizeof(x));
232*67e74705SXin Li // M_int captures both a & x
233*67e74705SXin Li ASSERT_CLOSURE_SIZE_EXACT(M_int, sizeof(x) + sizeof(int));
234*67e74705SXin Li // N_int_int captures both a & x
235*67e74705SXin Li ASSERT_CLOSURE_SIZE_EXACT(N_int_int, sizeof(x) + sizeof(int));
236*67e74705SXin Li auto M_double = L(3.14);
237*67e74705SXin Li ASSERT_CLOSURE_SIZE(M_double, sizeof(x) + sizeof(double));
238*67e74705SXin Li
239*67e74705SXin Li return 0;
240*67e74705SXin Li }
241*67e74705SXin Li auto run = foo();
242*67e74705SXin Li }
243*67e74705SXin Li
244*67e74705SXin Li }
245*67e74705SXin Li namespace more_nested_captures_1 {
246*67e74705SXin Li template<class T> struct Y {
fmore_nested_captures_1::Y247*67e74705SXin Li static void f(int, double, ...) { }
248*67e74705SXin Li template<class R>
fmore_nested_captures_1::Y249*67e74705SXin Li static void f(const int&, R, ...) { }
250*67e74705SXin Li template<class R>
foomore_nested_captures_1::Y251*67e74705SXin Li void foo(R t) {
252*67e74705SXin Li const int x = 10; //expected-note{{declared here}}
253*67e74705SXin Li auto L = [](auto a) {
254*67e74705SXin Li return [=](auto b) {
255*67e74705SXin Li return [=](auto c) {
256*67e74705SXin Li f(x, c, b, a); //expected-error{{reference to local variable 'x'}}
257*67e74705SXin Li return 0;
258*67e74705SXin Li };
259*67e74705SXin Li };
260*67e74705SXin Li };
261*67e74705SXin Li auto M = L(t);
262*67e74705SXin Li auto N = M('b');
263*67e74705SXin Li N(3.14);
264*67e74705SXin Li N(5); //expected-note{{in instantiation of}}
265*67e74705SXin Li }
266*67e74705SXin Li };
267*67e74705SXin Li Y<int> yi;
268*67e74705SXin Li int run = (yi.foo(3.14), 0); //expected-note{{in instantiation of}}
269*67e74705SXin Li }
270*67e74705SXin Li
271*67e74705SXin Li
272*67e74705SXin Li namespace more_nested_captures_1_1 {
273*67e74705SXin Li template<class T> struct Y {
fmore_nested_captures_1_1::Y274*67e74705SXin Li static void f(int, double, ...) { }
275*67e74705SXin Li template<class R>
fmore_nested_captures_1_1::Y276*67e74705SXin Li static void f(const int&, R, ...) { }
277*67e74705SXin Li template<class R>
foomore_nested_captures_1_1::Y278*67e74705SXin Li void foo(R t) {
279*67e74705SXin Li const int x = 10; //expected-note{{declared here}}
280*67e74705SXin Li auto L = [](auto a) {
281*67e74705SXin Li return [=](char b) {
282*67e74705SXin Li return [=](auto c) {
283*67e74705SXin Li f(x, c, b, a); //expected-error{{reference to local variable 'x'}}
284*67e74705SXin Li return 0;
285*67e74705SXin Li };
286*67e74705SXin Li };
287*67e74705SXin Li };
288*67e74705SXin Li auto M = L(t);
289*67e74705SXin Li auto N = M('b');
290*67e74705SXin Li N(3.14);
291*67e74705SXin Li N(5); //expected-note{{in instantiation of}}
292*67e74705SXin Li }
293*67e74705SXin Li };
294*67e74705SXin Li Y<int> yi;
295*67e74705SXin Li int run = (yi.foo(3.14), 0); //expected-note{{in instantiation of}}
296*67e74705SXin Li }
297*67e74705SXin Li namespace more_nested_captures_1_2 {
298*67e74705SXin Li template<class T> struct Y {
fmore_nested_captures_1_2::Y299*67e74705SXin Li static void f(int, double, ...) { }
300*67e74705SXin Li template<class R>
fmore_nested_captures_1_2::Y301*67e74705SXin Li static void f(const int&, R, ...) { }
302*67e74705SXin Li template<class R>
foomore_nested_captures_1_2::Y303*67e74705SXin Li void foo(R t) {
304*67e74705SXin Li const int x = 10;
305*67e74705SXin Li auto L = [=](auto a) {
306*67e74705SXin Li return [=](char b) {
307*67e74705SXin Li return [=](auto c) {
308*67e74705SXin Li f(x, c, b, a);
309*67e74705SXin Li return 0;
310*67e74705SXin Li };
311*67e74705SXin Li };
312*67e74705SXin Li };
313*67e74705SXin Li auto M = L(t);
314*67e74705SXin Li auto N = M('b');
315*67e74705SXin Li N(3.14);
316*67e74705SXin Li N(5);
317*67e74705SXin Li }
318*67e74705SXin Li };
319*67e74705SXin Li Y<int> yi;
320*67e74705SXin Li int run = (yi.foo(3.14), 0);
321*67e74705SXin Li }
322*67e74705SXin Li
323*67e74705SXin Li namespace more_nested_captures_1_3 {
324*67e74705SXin Li template<class T> struct Y {
fmore_nested_captures_1_3::Y325*67e74705SXin Li static void f(int, double, ...) { }
326*67e74705SXin Li template<class R>
fmore_nested_captures_1_3::Y327*67e74705SXin Li static void f(const int&, R, ...) { }
328*67e74705SXin Li template<class R>
foomore_nested_captures_1_3::Y329*67e74705SXin Li void foo(R t) {
330*67e74705SXin Li const int x = 10; //expected-note{{declared here}}
331*67e74705SXin Li auto L = [=](auto a) {
332*67e74705SXin Li return [](auto b) {
333*67e74705SXin Li const int y = 0;
334*67e74705SXin Li return [=](auto c) {
335*67e74705SXin Li f(x, c, b); //expected-error{{reference to local variable 'x'}}
336*67e74705SXin Li f(y, b, c);
337*67e74705SXin Li return 0;
338*67e74705SXin Li };
339*67e74705SXin Li };
340*67e74705SXin Li };
341*67e74705SXin Li auto M = L(t);
342*67e74705SXin Li auto N = M('b');
343*67e74705SXin Li N(3.14);
344*67e74705SXin Li N(5); //expected-note{{in instantiation of}}
345*67e74705SXin Li }
346*67e74705SXin Li };
347*67e74705SXin Li Y<int> yi;
348*67e74705SXin Li int run = (yi.foo(3.14), 0); //expected-note{{in instantiation of}}
349*67e74705SXin Li }
350*67e74705SXin Li
351*67e74705SXin Li
352*67e74705SXin Li namespace more_nested_captures_1_4 {
353*67e74705SXin Li template<class T> struct Y {
fmore_nested_captures_1_4::Y354*67e74705SXin Li static void f(int, double, ...) { }
355*67e74705SXin Li template<class R>
fmore_nested_captures_1_4::Y356*67e74705SXin Li static void f(const int&, R, ...) { }
357*67e74705SXin Li template<class R>
foomore_nested_captures_1_4::Y358*67e74705SXin Li void foo(R t) {
359*67e74705SXin Li const int x = 10; //expected-note{{declared here}}
360*67e74705SXin Li auto L = [=](auto a) {
361*67e74705SXin Li T t2{t};
362*67e74705SXin Li return [](auto b) {
363*67e74705SXin Li const int y = 0; //expected-note{{declared here}}
364*67e74705SXin Li return [](auto c) { //expected-note 2{{lambda expression begins here}}
365*67e74705SXin Li f(x, c); //expected-error{{variable 'x'}}
366*67e74705SXin Li f(y, c); //expected-error{{variable 'y'}}
367*67e74705SXin Li return 0;
368*67e74705SXin Li };
369*67e74705SXin Li };
370*67e74705SXin Li };
371*67e74705SXin Li auto M = L(t);
372*67e74705SXin Li auto N_char = M('b');
373*67e74705SXin Li N_char(3.14);
374*67e74705SXin Li auto N_double = M(3.14);
375*67e74705SXin Li N_double(3.14);
376*67e74705SXin Li N_char(3); //expected-note{{in instantiation of}}
377*67e74705SXin Li }
378*67e74705SXin Li };
379*67e74705SXin Li Y<int> yi;
380*67e74705SXin Li int run = (yi.foo('a'), 0); //expected-note{{in instantiation of}}
381*67e74705SXin Li }
382*67e74705SXin Li
383*67e74705SXin Li
384*67e74705SXin Li namespace more_nested_captures_2 {
385*67e74705SXin Li template<class T> struct Y {
fmore_nested_captures_2::Y386*67e74705SXin Li static void f(int, double) { }
387*67e74705SXin Li template<class R>
fmore_nested_captures_2::Y388*67e74705SXin Li static void f(const int&, R) { }
389*67e74705SXin Li template<class R>
foomore_nested_captures_2::Y390*67e74705SXin Li void foo(R t) {
391*67e74705SXin Li const int x = 10;
392*67e74705SXin Li auto L = [=](auto a) {
393*67e74705SXin Li return [=](auto b) {
394*67e74705SXin Li return [=](auto c) {
395*67e74705SXin Li f(x, c);
396*67e74705SXin Li return 0;
397*67e74705SXin Li };
398*67e74705SXin Li };
399*67e74705SXin Li };
400*67e74705SXin Li auto M = L(t);
401*67e74705SXin Li auto N = M('b');
402*67e74705SXin Li N(3);
403*67e74705SXin Li N(3.14);
404*67e74705SXin Li }
405*67e74705SXin Li };
406*67e74705SXin Li Y<int> yi;
407*67e74705SXin Li int run = (yi.foo(3.14), 0);
408*67e74705SXin Li
409*67e74705SXin Li }
410*67e74705SXin Li
411*67e74705SXin Li namespace more_nested_captures_3 {
412*67e74705SXin Li template<class T> struct Y {
fmore_nested_captures_3::Y413*67e74705SXin Li static void f(int, double) { }
414*67e74705SXin Li template<class R>
fmore_nested_captures_3::Y415*67e74705SXin Li static void f(const int&, R) { }
416*67e74705SXin Li template<class R>
foomore_nested_captures_3::Y417*67e74705SXin Li void foo(R t) {
418*67e74705SXin Li const int x = 10; //expected-note{{declared here}}
419*67e74705SXin Li auto L = [](auto a) {
420*67e74705SXin Li return [=](auto b) {
421*67e74705SXin Li return [=](auto c) {
422*67e74705SXin Li f(x, c); //expected-error{{reference to local variable 'x'}}
423*67e74705SXin Li return 0;
424*67e74705SXin Li };
425*67e74705SXin Li };
426*67e74705SXin Li };
427*67e74705SXin Li auto M = L(t);
428*67e74705SXin Li auto N = M('b');
429*67e74705SXin Li N(3); //expected-note{{in instantiation of}}
430*67e74705SXin Li N(3.14);
431*67e74705SXin Li }
432*67e74705SXin Li };
433*67e74705SXin Li Y<int> yi;
434*67e74705SXin Li int run = (yi.foo(3.14), 0); //expected-note{{in instantiation of}}
435*67e74705SXin Li
436*67e74705SXin Li }
437*67e74705SXin Li
438*67e74705SXin Li namespace more_nested_captures_4 {
439*67e74705SXin Li template<class T> struct Y {
fmore_nested_captures_4::Y440*67e74705SXin Li static void f(int, double) { }
441*67e74705SXin Li template<class R>
fmore_nested_captures_4::Y442*67e74705SXin Li static void f(const int&, R) { }
443*67e74705SXin Li template<class R>
foomore_nested_captures_4::Y444*67e74705SXin Li void foo(R t) {
445*67e74705SXin Li const int x = 10; //expected-note{{'x' declared here}}
446*67e74705SXin Li auto L = [](auto a) {
447*67e74705SXin Li return [=](char b) {
448*67e74705SXin Li return [=](auto c) {
449*67e74705SXin Li f(x, c); //expected-error{{reference to local variable 'x'}}
450*67e74705SXin Li return 0;
451*67e74705SXin Li };
452*67e74705SXin Li };
453*67e74705SXin Li };
454*67e74705SXin Li auto M = L(t);
455*67e74705SXin Li auto N = M('b');
456*67e74705SXin Li N(3); //expected-note{{in instantiation of}}
457*67e74705SXin Li N(3.14);
458*67e74705SXin Li }
459*67e74705SXin Li };
460*67e74705SXin Li Y<int> yi;
461*67e74705SXin Li int run = (yi.foo(3.14), 0); //expected-note{{in instantiation of}}
462*67e74705SXin Li
463*67e74705SXin Li }
464*67e74705SXin Li
465*67e74705SXin Li namespace more_nested_captures_5 {
466*67e74705SXin Li template<class T> struct Y {
fmore_nested_captures_5::Y467*67e74705SXin Li static void f(int, double) { }
468*67e74705SXin Li template<class R>
fmore_nested_captures_5::Y469*67e74705SXin Li static void f(const int&, R) { }
470*67e74705SXin Li template<class R>
foomore_nested_captures_5::Y471*67e74705SXin Li void foo(R t) {
472*67e74705SXin Li const int x = 10;
473*67e74705SXin Li auto L = [=](auto a) {
474*67e74705SXin Li return [=](char b) {
475*67e74705SXin Li return [=](auto c) {
476*67e74705SXin Li f(x, c);
477*67e74705SXin Li return 0;
478*67e74705SXin Li };
479*67e74705SXin Li };
480*67e74705SXin Li };
481*67e74705SXin Li auto M = L(t);
482*67e74705SXin Li auto N = M('b');
483*67e74705SXin Li N(3);
484*67e74705SXin Li N(3.14);
485*67e74705SXin Li }
486*67e74705SXin Li };
487*67e74705SXin Li Y<int> yi;
488*67e74705SXin Li int run = (yi.foo(3.14), 0);
489*67e74705SXin Li
490*67e74705SXin Li }
491*67e74705SXin Li
492*67e74705SXin Li namespace lambdas_in_NSDMIs {
493*67e74705SXin Li template<class T>
494*67e74705SXin Li struct L {
495*67e74705SXin Li T t{};
__anon59f5a0453902(auto b) 496*67e74705SXin Li T t2 = ([](auto a) { return [](auto b) { return b; };})(t)(t);
__anon59f5a0453a02lambdas_in_NSDMIs::L497*67e74705SXin Li T t3 = ([](auto a) { return a; })(t);
498*67e74705SXin Li };
499*67e74705SXin Li L<int> l;
500*67e74705SXin Li int run = l.t2;
501*67e74705SXin Li }
502*67e74705SXin Li namespace test_nested_decltypes_in_trailing_return_types {
foo()503*67e74705SXin Li int foo() {
504*67e74705SXin Li auto L = [](auto a) {
505*67e74705SXin Li return [](auto b, decltype(a) b2) -> decltype(a) {
506*67e74705SXin Li return decltype(a){};
507*67e74705SXin Li };
508*67e74705SXin Li };
509*67e74705SXin Li auto M = L(3.14);
510*67e74705SXin Li M('a', 6.26);
511*67e74705SXin Li return 0;
512*67e74705SXin Li }
513*67e74705SXin Li }
514*67e74705SXin Li
515*67e74705SXin Li namespace more_this_capture_1 {
516*67e74705SXin Li struct X {
fmore_this_capture_1::X517*67e74705SXin Li void f(int) { }
fmore_this_capture_1::X518*67e74705SXin Li static void f(double) { }
foomore_this_capture_1::X519*67e74705SXin Li void foo() {
520*67e74705SXin Li {
521*67e74705SXin Li auto L = [=](auto a) {
522*67e74705SXin Li f(a);
523*67e74705SXin Li };
524*67e74705SXin Li L(3);
525*67e74705SXin Li L(3.13);
526*67e74705SXin Li }
527*67e74705SXin Li {
528*67e74705SXin Li auto L = [](auto a) {
529*67e74705SXin Li f(a); //expected-error{{this}}
530*67e74705SXin Li };
531*67e74705SXin Li L(3.13);
532*67e74705SXin Li L(2); //expected-note{{in instantiation}}
533*67e74705SXin Li }
534*67e74705SXin Li }
535*67e74705SXin Li
gmore_this_capture_1::X536*67e74705SXin Li int g() {
537*67e74705SXin Li auto L = [=](auto a) {
538*67e74705SXin Li return [](int i) {
539*67e74705SXin Li return [=](auto b) {
540*67e74705SXin Li f(b);
541*67e74705SXin Li int x = i;
542*67e74705SXin Li };
543*67e74705SXin Li };
544*67e74705SXin Li };
545*67e74705SXin Li auto M = L(0.0);
546*67e74705SXin Li auto N = M(3);
547*67e74705SXin Li N(5.32); // OK
548*67e74705SXin Li return 0;
549*67e74705SXin Li }
550*67e74705SXin Li };
551*67e74705SXin Li int run = X{}.g();
552*67e74705SXin Li }
553*67e74705SXin Li namespace more_this_capture_1_1 {
554*67e74705SXin Li struct X {
fmore_this_capture_1_1::X555*67e74705SXin Li void f(int) { }
fmore_this_capture_1_1::X556*67e74705SXin Li static void f(double) { }
557*67e74705SXin Li
gmore_this_capture_1_1::X558*67e74705SXin Li int g() {
559*67e74705SXin Li auto L = [=](auto a) {
560*67e74705SXin Li return [](int i) {
561*67e74705SXin Li return [=](auto b) {
562*67e74705SXin Li f(decltype(a){}); //expected-error{{this}}
563*67e74705SXin Li int x = i;
564*67e74705SXin Li };
565*67e74705SXin Li };
566*67e74705SXin Li };
567*67e74705SXin Li auto M = L(0.0);
568*67e74705SXin Li auto N = M(3);
569*67e74705SXin Li N(5.32); // OK
570*67e74705SXin Li L(3); // expected-note{{instantiation}}
571*67e74705SXin Li return 0;
572*67e74705SXin Li }
573*67e74705SXin Li };
574*67e74705SXin Li int run = X{}.g();
575*67e74705SXin Li }
576*67e74705SXin Li
577*67e74705SXin Li namespace more_this_capture_1_1_1 {
578*67e74705SXin Li struct X {
fmore_this_capture_1_1_1::X579*67e74705SXin Li void f(int) { }
fmore_this_capture_1_1_1::X580*67e74705SXin Li static void f(double) { }
581*67e74705SXin Li
gmore_this_capture_1_1_1::X582*67e74705SXin Li int g() {
583*67e74705SXin Li auto L = [=](auto a) {
584*67e74705SXin Li return [](auto b) {
585*67e74705SXin Li return [=](int i) {
586*67e74705SXin Li f(b);
587*67e74705SXin Li f(decltype(a){}); //expected-error{{this}}
588*67e74705SXin Li };
589*67e74705SXin Li };
590*67e74705SXin Li };
591*67e74705SXin Li auto M = L(0.0); // OK
592*67e74705SXin Li auto N = M(3.3); //OK
593*67e74705SXin Li auto M_int = L(0); //expected-note{{instantiation}}
594*67e74705SXin Li return 0;
595*67e74705SXin Li }
596*67e74705SXin Li };
597*67e74705SXin Li int run = X{}.g();
598*67e74705SXin Li }
599*67e74705SXin Li
600*67e74705SXin Li
601*67e74705SXin Li namespace more_this_capture_1_1_1_1 {
602*67e74705SXin Li struct X {
fmore_this_capture_1_1_1_1::X603*67e74705SXin Li void f(int) { }
fmore_this_capture_1_1_1_1::X604*67e74705SXin Li static void f(double) { }
605*67e74705SXin Li
gmore_this_capture_1_1_1_1::X606*67e74705SXin Li int g() {
607*67e74705SXin Li auto L = [=](auto a) {
608*67e74705SXin Li return [](auto b) {
609*67e74705SXin Li return [=](int i) {
610*67e74705SXin Li f(b); //expected-error{{this}}
611*67e74705SXin Li f(decltype(a){});
612*67e74705SXin Li };
613*67e74705SXin Li };
614*67e74705SXin Li };
615*67e74705SXin Li auto M_double = L(0.0); // OK
616*67e74705SXin Li auto N = M_double(3); //expected-note{{instantiation}}
617*67e74705SXin Li
618*67e74705SXin Li return 0;
619*67e74705SXin Li }
620*67e74705SXin Li };
621*67e74705SXin Li int run = X{}.g();
622*67e74705SXin Li }
623*67e74705SXin Li
624*67e74705SXin Li namespace more_this_capture_2 {
625*67e74705SXin Li struct X {
fmore_this_capture_2::X626*67e74705SXin Li void f(int) { }
fmore_this_capture_2::X627*67e74705SXin Li static void f(double) { }
628*67e74705SXin Li
gmore_this_capture_2::X629*67e74705SXin Li int g() {
630*67e74705SXin Li auto L = [=](auto a) {
631*67e74705SXin Li return [](int i) {
632*67e74705SXin Li return [=](auto b) {
633*67e74705SXin Li f(b); //expected-error{{'this' cannot}}
634*67e74705SXin Li int x = i;
635*67e74705SXin Li };
636*67e74705SXin Li };
637*67e74705SXin Li };
638*67e74705SXin Li auto M = L(0.0);
639*67e74705SXin Li auto N = M(3);
640*67e74705SXin Li N(5); // NOT OK expected-note{{in instantiation of}}
641*67e74705SXin Li return 0;
642*67e74705SXin Li }
643*67e74705SXin Li };
644*67e74705SXin Li int run = X{}.g();
645*67e74705SXin Li }
646*67e74705SXin Li namespace diagnose_errors_early_in_generic_lambdas {
647*67e74705SXin Li
foo()648*67e74705SXin Li int foo()
649*67e74705SXin Li {
650*67e74705SXin Li
651*67e74705SXin Li { // This variable is used and must be caught early, do not need instantiation
652*67e74705SXin Li const int x = 0; //expected-note{{declared}}
653*67e74705SXin Li auto L = [](auto a) { //expected-note{{begins}}
654*67e74705SXin Li const int &r = x; //expected-error{{variable}}
655*67e74705SXin Li };
656*67e74705SXin Li }
657*67e74705SXin Li { // This variable is not used
658*67e74705SXin Li const int x = 0;
659*67e74705SXin Li auto L = [](auto a) {
660*67e74705SXin Li int i = x;
661*67e74705SXin Li };
662*67e74705SXin Li }
663*67e74705SXin Li {
664*67e74705SXin Li
665*67e74705SXin Li const int x = 0; //expected-note{{declared}}
666*67e74705SXin Li auto L = [=](auto a) { // <-- #A
667*67e74705SXin Li const int y = 0;
668*67e74705SXin Li return [](auto b) { //expected-note{{begins}}
669*67e74705SXin Li int c[sizeof(b)];
670*67e74705SXin Li f(x, c);
671*67e74705SXin Li f(y, c);
672*67e74705SXin Li int i = x;
673*67e74705SXin Li // This use will always be an error regardless of instantatiation
674*67e74705SXin Li // so diagnose this early.
675*67e74705SXin Li const int &r = x; //expected-error{{variable}}
676*67e74705SXin Li };
677*67e74705SXin Li };
678*67e74705SXin Li
679*67e74705SXin Li }
680*67e74705SXin Li return 0;
681*67e74705SXin Li }
682*67e74705SXin Li
683*67e74705SXin Li int run = foo();
684*67e74705SXin Li }
685*67e74705SXin Li
686*67e74705SXin Li namespace generic_nongenerics_interleaved_1 {
foo()687*67e74705SXin Li int foo() {
688*67e74705SXin Li {
689*67e74705SXin Li auto L = [](int a) {
690*67e74705SXin Li int y = 10;
691*67e74705SXin Li return [=](auto b) {
692*67e74705SXin Li return a + y;
693*67e74705SXin Li };
694*67e74705SXin Li };
695*67e74705SXin Li auto M = L(3);
696*67e74705SXin Li M(5);
697*67e74705SXin Li }
698*67e74705SXin Li {
699*67e74705SXin Li int x;
700*67e74705SXin Li auto L = [](int a) {
701*67e74705SXin Li int y = 10;
702*67e74705SXin Li return [=](auto b) {
703*67e74705SXin Li return a + y;
704*67e74705SXin Li };
705*67e74705SXin Li };
706*67e74705SXin Li auto M = L(3);
707*67e74705SXin Li M(5);
708*67e74705SXin Li }
709*67e74705SXin Li {
710*67e74705SXin Li // FIXME: why are there 2 error messages here?
711*67e74705SXin Li int x;
712*67e74705SXin Li auto L = [](auto a) { //expected-note {{declared here}}
713*67e74705SXin Li int y = 10; //expected-note {{declared here}}
714*67e74705SXin Li return [](int b) { //expected-note 2{{expression begins here}}
715*67e74705SXin Li return [=] (auto c) {
716*67e74705SXin Li return a + y; //expected-error 2{{cannot be implicitly captured}}
717*67e74705SXin Li };
718*67e74705SXin Li };
719*67e74705SXin Li };
720*67e74705SXin Li }
721*67e74705SXin Li {
722*67e74705SXin Li int x;
723*67e74705SXin Li auto L = [](auto a) {
724*67e74705SXin Li int y = 10;
725*67e74705SXin Li return [=](int b) {
726*67e74705SXin Li return [=] (auto c) {
727*67e74705SXin Li return a + y;
728*67e74705SXin Li };
729*67e74705SXin Li };
730*67e74705SXin Li };
731*67e74705SXin Li }
732*67e74705SXin Li return 1;
733*67e74705SXin Li }
734*67e74705SXin Li
735*67e74705SXin Li int run = foo();
736*67e74705SXin Li }
737*67e74705SXin Li namespace dont_capture_refs_if_initialized_with_constant_expressions {
738*67e74705SXin Li
foo(int i)739*67e74705SXin Li auto foo(int i) {
740*67e74705SXin Li // This is surprisingly not odr-used within the lambda!
741*67e74705SXin Li static int j;
742*67e74705SXin Li j = i;
743*67e74705SXin Li int &ref_j = j;
744*67e74705SXin Li return [](auto a) { return ref_j; }; // ok
745*67e74705SXin Li }
746*67e74705SXin Li
747*67e74705SXin Li template<class T>
foo2(T t)748*67e74705SXin Li auto foo2(T t) {
749*67e74705SXin Li // This is surprisingly not odr-used within the lambda!
750*67e74705SXin Li static T j;
751*67e74705SXin Li j = t;
752*67e74705SXin Li T &ref_j = j;
753*67e74705SXin Li return [](auto a) { return ref_j; }; // ok
754*67e74705SXin Li }
755*67e74705SXin Li
do_test()756*67e74705SXin Li int do_test() {
757*67e74705SXin Li auto L = foo(3);
758*67e74705SXin Li auto L_int = L(3);
759*67e74705SXin Li auto L_char = L('a');
760*67e74705SXin Li auto L1 = foo2(3.14);
761*67e74705SXin Li auto L1_int = L1(3);
762*67e74705SXin Li auto L1_char = L1('a');
763*67e74705SXin Li return 0;
764*67e74705SXin Li }
765*67e74705SXin Li
766*67e74705SXin Li } // dont_capture_refs_if_initialized_with_constant_expressions
767*67e74705SXin Li
768*67e74705SXin Li namespace test_conversion_to_fptr {
769*67e74705SXin Li
770*67e74705SXin Li template<class T> struct X {
771*67e74705SXin Li
__anon59f5a0455d02test_conversion_to_fptr::X772*67e74705SXin Li T (*fp)(T) = [](auto a) { return a; };
773*67e74705SXin Li
774*67e74705SXin Li };
775*67e74705SXin Li
776*67e74705SXin Li X<int> xi;
777*67e74705SXin Li
778*67e74705SXin Li template<class T>
fooT(T t,T (* fp)(T)=[](auto a){})779*67e74705SXin Li void fooT(T t, T (*fp)(T) = [](auto a) { return a; }) {
780*67e74705SXin Li fp(t);
781*67e74705SXin Li }
782*67e74705SXin Li
test()783*67e74705SXin Li int test() {
784*67e74705SXin Li {
785*67e74705SXin Li auto L = [](auto a) { return a; };
786*67e74705SXin Li int (*fp)(int) = L;
787*67e74705SXin Li fp(5);
788*67e74705SXin Li L(3);
789*67e74705SXin Li char (*fc)(char) = L;
790*67e74705SXin Li fc('b');
791*67e74705SXin Li L('c');
792*67e74705SXin Li double (*fd)(double) = L;
793*67e74705SXin Li fd(3.14);
794*67e74705SXin Li fd(6.26);
795*67e74705SXin Li L(4.25);
796*67e74705SXin Li }
797*67e74705SXin Li {
798*67e74705SXin Li auto L = [](auto a) ->int { return a; }; //expected-note 2{{candidate template ignored}}
799*67e74705SXin Li int (*fp)(int) = L;
800*67e74705SXin Li char (*fc)(char) = L; //expected-error{{no viable conversion}}
801*67e74705SXin Li double (*fd)(double) = L; //expected-error{{no viable conversion}}
802*67e74705SXin Li }
803*67e74705SXin Li {
804*67e74705SXin Li int x = 5;
805*67e74705SXin Li auto L = [=](auto b, char c = 'x') {
806*67e74705SXin Li int i = x;
807*67e74705SXin Li return [](auto a) ->decltype(a) { return a; };
808*67e74705SXin Li };
809*67e74705SXin Li int (*fp)(int) = L(8);
810*67e74705SXin Li fp(5);
811*67e74705SXin Li L(3);
812*67e74705SXin Li char (*fc)(char) = L('a');
813*67e74705SXin Li fc('b');
814*67e74705SXin Li L('c');
815*67e74705SXin Li double (*fd)(double) = L(3.14);
816*67e74705SXin Li fd(3.14);
817*67e74705SXin Li fd(6.26);
818*67e74705SXin Li
819*67e74705SXin Li }
820*67e74705SXin Li {
821*67e74705SXin Li auto L = [=](auto b) {
822*67e74705SXin Li return [](auto a) ->decltype(b)* { return (decltype(b)*)0; };
823*67e74705SXin Li };
824*67e74705SXin Li int* (*fp)(int) = L(8);
825*67e74705SXin Li fp(5);
826*67e74705SXin Li L(3);
827*67e74705SXin Li char* (*fc)(char) = L('a');
828*67e74705SXin Li fc('b');
829*67e74705SXin Li L('c');
830*67e74705SXin Li double* (*fd)(double) = L(3.14);
831*67e74705SXin Li fd(3.14);
832*67e74705SXin Li fd(6.26);
833*67e74705SXin Li }
834*67e74705SXin Li {
835*67e74705SXin Li auto L = [=](auto b) {
836*67e74705SXin Li return [](auto a) ->decltype(b)* { return (decltype(b)*)0; }; //expected-note{{candidate template ignored}}
837*67e74705SXin Li };
838*67e74705SXin Li char* (*fp)(int) = L('8');
839*67e74705SXin Li fp(5);
840*67e74705SXin Li char* (*fc)(char) = L('a');
841*67e74705SXin Li fc('b');
842*67e74705SXin Li double* (*fi)(int) = L(3.14);
843*67e74705SXin Li fi(5);
844*67e74705SXin Li int* (*fi2)(int) = L(3.14); //expected-error{{no viable conversion}}
845*67e74705SXin Li }
846*67e74705SXin Li
847*67e74705SXin Li {
848*67e74705SXin Li auto L = [=](auto b) {
849*67e74705SXin Li return [](auto a) {
850*67e74705SXin Li return [=](auto c) {
851*67e74705SXin Li return [](auto d) ->decltype(a + b + c + d) { return d; };
852*67e74705SXin Li };
853*67e74705SXin Li };
854*67e74705SXin Li };
855*67e74705SXin Li int (*fp)(int) = L('8')(3)(short{});
856*67e74705SXin Li double (*fs)(char) = L(3.14)(short{})('4');
857*67e74705SXin Li }
858*67e74705SXin Li
859*67e74705SXin Li fooT(3);
860*67e74705SXin Li fooT('a');
861*67e74705SXin Li fooT(3.14);
862*67e74705SXin Li fooT("abcdefg");
863*67e74705SXin Li return 0;
864*67e74705SXin Li }
865*67e74705SXin Li int run2 = test();
866*67e74705SXin Li
867*67e74705SXin Li }
868*67e74705SXin Li
869*67e74705SXin Li
870*67e74705SXin Li namespace this_capture {
f(char,int)871*67e74705SXin Li void f(char, int) { }
872*67e74705SXin Li template<class T>
f(T,const int &)873*67e74705SXin Li void f(T, const int&) { }
874*67e74705SXin Li
875*67e74705SXin Li struct X {
876*67e74705SXin Li int x = 0;
foothis_capture::X877*67e74705SXin Li void foo() {
878*67e74705SXin Li auto L = [=](auto a) {
879*67e74705SXin Li return [=](auto b) {
880*67e74705SXin Li //f(a, x++);
881*67e74705SXin Li x++;
882*67e74705SXin Li };
883*67e74705SXin Li };
884*67e74705SXin Li L('a')(5);
885*67e74705SXin Li L('b')(4);
886*67e74705SXin Li L(3.14)('3');
887*67e74705SXin Li
888*67e74705SXin Li }
889*67e74705SXin Li
890*67e74705SXin Li };
891*67e74705SXin Li
892*67e74705SXin Li int run = (X{}.foo(), 0);
893*67e74705SXin Li
894*67e74705SXin Li namespace this_capture_unresolvable {
895*67e74705SXin Li struct X {
fthis_capture::this_capture_unresolvable::X896*67e74705SXin Li void f(int) { }
fthis_capture::this_capture_unresolvable::X897*67e74705SXin Li static void f(double) { }
898*67e74705SXin Li
gthis_capture::this_capture_unresolvable::X899*67e74705SXin Li int g() {
900*67e74705SXin Li auto lam = [=](auto a) { f(a); }; // captures 'this'
901*67e74705SXin Li lam(0); // ok.
902*67e74705SXin Li lam(0.0); // ok.
903*67e74705SXin Li return 0;
904*67e74705SXin Li }
g2this_capture::this_capture_unresolvable::X905*67e74705SXin Li int g2() {
906*67e74705SXin Li auto lam = [](auto a) { f(a); }; // expected-error{{'this'}}
907*67e74705SXin Li lam(0); // expected-note{{in instantiation of}}
908*67e74705SXin Li lam(0.0); // ok.
909*67e74705SXin Li return 0;
910*67e74705SXin Li }
__anon59f5a0456d02this_capture::this_capture_unresolvable::X911*67e74705SXin Li double (*fd)(double) = [](auto a) { f(a); return a; };
912*67e74705SXin Li
913*67e74705SXin Li };
914*67e74705SXin Li
915*67e74705SXin Li int run = X{}.g();
916*67e74705SXin Li
917*67e74705SXin Li }
918*67e74705SXin Li
919*67e74705SXin Li namespace check_nsdmi_and_this_capture_of_member_functions {
920*67e74705SXin Li
921*67e74705SXin Li struct FunctorDouble {
FunctorDoublethis_capture::check_nsdmi_and_this_capture_of_member_functions::FunctorDouble922*67e74705SXin Li template<class T> FunctorDouble(T t) { t(2.14); };
923*67e74705SXin Li };
924*67e74705SXin Li struct FunctorInt {
FunctorIntthis_capture::check_nsdmi_and_this_capture_of_member_functions::FunctorInt925*67e74705SXin Li template<class T> FunctorInt(T t) { t(2); }; //expected-note{{in instantiation of}}
926*67e74705SXin Li };
927*67e74705SXin Li
928*67e74705SXin Li template<class T> struct YUnresolvable {
fthis_capture::check_nsdmi_and_this_capture_of_member_functions::YUnresolvable929*67e74705SXin Li void f(int) { }
fthis_capture::check_nsdmi_and_this_capture_of_member_functions::YUnresolvable930*67e74705SXin Li static void f(double) { }
931*67e74705SXin Li
__anon59f5a0456e02this_capture::check_nsdmi_and_this_capture_of_member_functions::YUnresolvable932*67e74705SXin Li T t = [](auto a) { f(a); return a; };
__anon59f5a0456f02this_capture::check_nsdmi_and_this_capture_of_member_functions::YUnresolvable933*67e74705SXin Li T t2 = [=](auto b) { f(b); return b; };
934*67e74705SXin Li };
935*67e74705SXin Li
936*67e74705SXin Li template<class T> struct YUnresolvable2 {
fthis_capture::check_nsdmi_and_this_capture_of_member_functions::YUnresolvable2937*67e74705SXin Li void f(int) { }
fthis_capture::check_nsdmi_and_this_capture_of_member_functions::YUnresolvable2938*67e74705SXin Li static void f(double) { }
939*67e74705SXin Li
__anon59f5a0457002this_capture::check_nsdmi_and_this_capture_of_member_functions::YUnresolvable2940*67e74705SXin Li T t = [](auto a) { f(a); return a; }; //expected-error{{'this'}} \
941*67e74705SXin Li //expected-note{{in instantiation of}}
__anon59f5a0457102this_capture::check_nsdmi_and_this_capture_of_member_functions::YUnresolvable2942*67e74705SXin Li T t2 = [=](auto b) { f(b); return b; };
943*67e74705SXin Li };
944*67e74705SXin Li
945*67e74705SXin Li
946*67e74705SXin Li YUnresolvable<FunctorDouble> yud;
947*67e74705SXin Li // This will cause an error since it call's with an int and calls a member function.
948*67e74705SXin Li YUnresolvable2<FunctorInt> yui;
949*67e74705SXin Li
950*67e74705SXin Li
951*67e74705SXin Li template<class T> struct YOnlyStatic {
fthis_capture::check_nsdmi_and_this_capture_of_member_functions::YOnlyStatic952*67e74705SXin Li static void f(double) { }
953*67e74705SXin Li
__anon59f5a0457202this_capture::check_nsdmi_and_this_capture_of_member_functions::YOnlyStatic954*67e74705SXin Li T t = [](auto a) { f(a); return a; };
955*67e74705SXin Li };
956*67e74705SXin Li YOnlyStatic<FunctorDouble> yos;
957*67e74705SXin Li template<class T> struct YOnlyNonStatic {
fthis_capture::check_nsdmi_and_this_capture_of_member_functions::YOnlyNonStatic958*67e74705SXin Li void f(int) { }
959*67e74705SXin Li
__anon59f5a0457302this_capture::check_nsdmi_and_this_capture_of_member_functions::YOnlyNonStatic960*67e74705SXin Li T t = [](auto a) { f(a); return a; }; //expected-error{{'this'}}
961*67e74705SXin Li };
962*67e74705SXin Li
963*67e74705SXin Li
964*67e74705SXin Li }
965*67e74705SXin Li
966*67e74705SXin Li
967*67e74705SXin Li namespace check_nsdmi_and_this_capture_of_data_members {
968*67e74705SXin Li
969*67e74705SXin Li struct FunctorDouble {
FunctorDoublethis_capture::check_nsdmi_and_this_capture_of_data_members::FunctorDouble970*67e74705SXin Li template<class T> FunctorDouble(T t) { t(2.14); };
971*67e74705SXin Li };
972*67e74705SXin Li struct FunctorInt {
FunctorIntthis_capture::check_nsdmi_and_this_capture_of_data_members::FunctorInt973*67e74705SXin Li template<class T> FunctorInt(T t) { t(2); };
974*67e74705SXin Li };
975*67e74705SXin Li
976*67e74705SXin Li template<class T> struct YThisCapture {
977*67e74705SXin Li const int x = 10;
978*67e74705SXin Li static double d;
__anon59f5a0457402this_capture::check_nsdmi_and_this_capture_of_data_members::YThisCapture979*67e74705SXin Li T t = [](auto a) { return x; }; //expected-error{{'this'}}
__anon59f5a0457502this_capture::check_nsdmi_and_this_capture_of_data_members::YThisCapture980*67e74705SXin Li T t2 = [](auto b) { return d; };
__anon59f5a0457602this_capture::check_nsdmi_and_this_capture_of_data_members::YThisCapture981*67e74705SXin Li T t3 = [this](auto a) {
982*67e74705SXin Li return [=](auto b) {
983*67e74705SXin Li return x;
984*67e74705SXin Li };
985*67e74705SXin Li };
__anon59f5a0457802this_capture::check_nsdmi_and_this_capture_of_data_members::YThisCapture986*67e74705SXin Li T t4 = [=](auto a) {
987*67e74705SXin Li return [=](auto b) {
988*67e74705SXin Li return x;
989*67e74705SXin Li };
990*67e74705SXin Li };
__anon59f5a0457a02this_capture::check_nsdmi_and_this_capture_of_data_members::YThisCapture991*67e74705SXin Li T t5 = [](auto a) {
992*67e74705SXin Li return [=](auto b) {
993*67e74705SXin Li return x; //expected-error{{'this'}}
994*67e74705SXin Li };
995*67e74705SXin Li };
996*67e74705SXin Li };
997*67e74705SXin Li
998*67e74705SXin Li template<class T> double YThisCapture<T>::d = 3.14;
999*67e74705SXin Li
1000*67e74705SXin Li
1001*67e74705SXin Li }
1002*67e74705SXin Li
1003*67e74705SXin Li
1004*67e74705SXin Li #ifdef DELAYED_TEMPLATE_PARSING
foo_no_error(T t)1005*67e74705SXin Li template<class T> void foo_no_error(T t) {
1006*67e74705SXin Li auto L = []()
1007*67e74705SXin Li { return t; };
1008*67e74705SXin Li }
foo(T t)1009*67e74705SXin Li template<class T> void foo(T t) { //expected-note 2{{declared here}}
1010*67e74705SXin Li auto L = []() //expected-note 2{{begins here}}
1011*67e74705SXin Li { return t; }; //expected-error 2{{cannot be implicitly captured}}
1012*67e74705SXin Li }
1013*67e74705SXin Li template void foo(int); //expected-note{{in instantiation of}}
1014*67e74705SXin Li
1015*67e74705SXin Li #else
1016*67e74705SXin Li
foo(T t)1017*67e74705SXin Li template<class T> void foo(T t) { //expected-note{{declared here}}
1018*67e74705SXin Li auto L = []() //expected-note{{begins here}}
1019*67e74705SXin Li { return t; }; //expected-error{{cannot be implicitly captured}}
1020*67e74705SXin Li }
1021*67e74705SXin Li
1022*67e74705SXin Li #endif
1023*67e74705SXin Li }
1024*67e74705SXin Li
1025*67e74705SXin Li namespace no_this_capture_for_static {
1026*67e74705SXin Li
1027*67e74705SXin Li struct X {
fno_this_capture_for_static::X1028*67e74705SXin Li static void f(double) { }
1029*67e74705SXin Li
gno_this_capture_for_static::X1030*67e74705SXin Li int g() {
1031*67e74705SXin Li auto lam = [=](auto a) { f(a); };
1032*67e74705SXin Li lam(0); // ok.
1033*67e74705SXin Li ASSERT_NO_CAPTURES(lam);
1034*67e74705SXin Li return 0;
1035*67e74705SXin Li }
1036*67e74705SXin Li };
1037*67e74705SXin Li
1038*67e74705SXin Li int run = X{}.g();
1039*67e74705SXin Li }
1040*67e74705SXin Li
1041*67e74705SXin Li namespace this_capture_for_non_static {
1042*67e74705SXin Li
1043*67e74705SXin Li struct X {
fthis_capture_for_non_static::X1044*67e74705SXin Li void f(double) { }
1045*67e74705SXin Li
gthis_capture_for_non_static::X1046*67e74705SXin Li int g() {
1047*67e74705SXin Li auto L = [=](auto a) { f(a); };
1048*67e74705SXin Li L(0);
1049*67e74705SXin Li auto L2 = [](auto a) { f(a); }; //expected-error {{cannot be implicitly captured}}
1050*67e74705SXin Li return 0;
1051*67e74705SXin Li }
1052*67e74705SXin Li };
1053*67e74705SXin Li
1054*67e74705SXin Li int run = X{}.g();
1055*67e74705SXin Li }
1056*67e74705SXin Li
1057*67e74705SXin Li namespace this_captures_with_num_args_disambiguation {
1058*67e74705SXin Li
1059*67e74705SXin Li struct X {
fthis_captures_with_num_args_disambiguation::X1060*67e74705SXin Li void f(int) { }
fthis_captures_with_num_args_disambiguation::X1061*67e74705SXin Li static void f(double, int i) { }
gthis_captures_with_num_args_disambiguation::X1062*67e74705SXin Li int g() {
1063*67e74705SXin Li auto lam = [](auto a) { f(a, a); };
1064*67e74705SXin Li lam(0);
1065*67e74705SXin Li return 0;
1066*67e74705SXin Li }
1067*67e74705SXin Li };
1068*67e74705SXin Li
1069*67e74705SXin Li int run = X{}.g();
1070*67e74705SXin Li }
1071*67e74705SXin Li namespace enclosing_function_is_template_this_capture {
1072*67e74705SXin Li // Only error if the instantiation tries to use the member function.
1073*67e74705SXin Li struct X {
fenclosing_function_is_template_this_capture::X1074*67e74705SXin Li void f(int) { }
fenclosing_function_is_template_this_capture::X1075*67e74705SXin Li static void f(double) { }
1076*67e74705SXin Li template<class T>
genclosing_function_is_template_this_capture::X1077*67e74705SXin Li int g(T t) {
1078*67e74705SXin Li auto L = [](auto a) { f(a); }; //expected-error{{'this'}}
1079*67e74705SXin Li L(t); // expected-note{{in instantiation of}}
1080*67e74705SXin Li return 0;
1081*67e74705SXin Li }
1082*67e74705SXin Li };
1083*67e74705SXin Li
1084*67e74705SXin Li int run = X{}.g(0.0); // OK.
1085*67e74705SXin Li int run2 = X{}.g(0); // expected-note{{in instantiation of}}
1086*67e74705SXin Li
1087*67e74705SXin Li
1088*67e74705SXin Li }
1089*67e74705SXin Li
1090*67e74705SXin Li namespace enclosing_function_is_template_this_capture_2 {
1091*67e74705SXin Li // This should error, even if not instantiated, since
1092*67e74705SXin Li // this would need to be captured.
1093*67e74705SXin Li struct X {
fenclosing_function_is_template_this_capture_2::X1094*67e74705SXin Li void f(int) { }
1095*67e74705SXin Li template<class T>
genclosing_function_is_template_this_capture_2::X1096*67e74705SXin Li int g(T t) {
1097*67e74705SXin Li auto L = [](auto a) { f(a); }; //expected-error{{'this'}}
1098*67e74705SXin Li L(t);
1099*67e74705SXin Li return 0;
1100*67e74705SXin Li }
1101*67e74705SXin Li };
1102*67e74705SXin Li
1103*67e74705SXin Li }
1104*67e74705SXin Li
1105*67e74705SXin Li
1106*67e74705SXin Li namespace enclosing_function_is_template_this_capture_3 {
1107*67e74705SXin Li // This should not error, this does not need to be captured.
1108*67e74705SXin Li struct X {
fenclosing_function_is_template_this_capture_3::X1109*67e74705SXin Li static void f(int) { }
1110*67e74705SXin Li template<class T>
genclosing_function_is_template_this_capture_3::X1111*67e74705SXin Li int g(T t) {
1112*67e74705SXin Li auto L = [](auto a) { f(a); };
1113*67e74705SXin Li L(t);
1114*67e74705SXin Li return 0;
1115*67e74705SXin Li }
1116*67e74705SXin Li };
1117*67e74705SXin Li
1118*67e74705SXin Li int run = X{}.g(0.0); // OK.
1119*67e74705SXin Li int run2 = X{}.g(0); // OK.
1120*67e74705SXin Li
1121*67e74705SXin Li }
1122*67e74705SXin Li
1123*67e74705SXin Li namespace nested_this_capture_1 {
1124*67e74705SXin Li struct X {
fnested_this_capture_1::X1125*67e74705SXin Li void f(int) { }
fnested_this_capture_1::X1126*67e74705SXin Li static void f(double) { }
1127*67e74705SXin Li
gnested_this_capture_1::X1128*67e74705SXin Li int g() {
1129*67e74705SXin Li auto L = [=](auto a) {
1130*67e74705SXin Li return [this]() {
1131*67e74705SXin Li return [=](auto b) {
1132*67e74705SXin Li f(b);
1133*67e74705SXin Li };
1134*67e74705SXin Li };
1135*67e74705SXin Li };
1136*67e74705SXin Li auto M = L(0);
1137*67e74705SXin Li auto N = M();
1138*67e74705SXin Li N(5);
1139*67e74705SXin Li return 0;
1140*67e74705SXin Li }
1141*67e74705SXin Li };
1142*67e74705SXin Li
1143*67e74705SXin Li int run = X{}.g();
1144*67e74705SXin Li
1145*67e74705SXin Li }
1146*67e74705SXin Li
1147*67e74705SXin Li
1148*67e74705SXin Li namespace nested_this_capture_2 {
1149*67e74705SXin Li struct X {
fnested_this_capture_2::X1150*67e74705SXin Li void f(int) { }
fnested_this_capture_2::X1151*67e74705SXin Li static void f(double) { }
1152*67e74705SXin Li
gnested_this_capture_2::X1153*67e74705SXin Li int g() {
1154*67e74705SXin Li auto L = [=](auto a) {
1155*67e74705SXin Li return [&]() {
1156*67e74705SXin Li return [=](auto b) {
1157*67e74705SXin Li f(b);
1158*67e74705SXin Li };
1159*67e74705SXin Li };
1160*67e74705SXin Li };
1161*67e74705SXin Li auto M = L(0);
1162*67e74705SXin Li auto N = M();
1163*67e74705SXin Li N(5);
1164*67e74705SXin Li N(3.14);
1165*67e74705SXin Li return 0;
1166*67e74705SXin Li }
1167*67e74705SXin Li };
1168*67e74705SXin Li
1169*67e74705SXin Li int run = X{}.g();
1170*67e74705SXin Li
1171*67e74705SXin Li }
1172*67e74705SXin Li
1173*67e74705SXin Li namespace nested_this_capture_3_1 {
1174*67e74705SXin Li struct X {
1175*67e74705SXin Li template<class T>
fnested_this_capture_3_1::X1176*67e74705SXin Li void f(int, T t) { }
1177*67e74705SXin Li template<class T>
fnested_this_capture_3_1::X1178*67e74705SXin Li static void f(double, T t) { }
1179*67e74705SXin Li
gnested_this_capture_3_1::X1180*67e74705SXin Li int g() {
1181*67e74705SXin Li auto L = [=](auto a) {
1182*67e74705SXin Li return [&](auto c) {
1183*67e74705SXin Li return [=](auto b) {
1184*67e74705SXin Li f(b, c);
1185*67e74705SXin Li };
1186*67e74705SXin Li };
1187*67e74705SXin Li };
1188*67e74705SXin Li auto M = L(0);
1189*67e74705SXin Li auto N = M('a');
1190*67e74705SXin Li N(5);
1191*67e74705SXin Li N(3.14);
1192*67e74705SXin Li return 0;
1193*67e74705SXin Li }
1194*67e74705SXin Li };
1195*67e74705SXin Li
1196*67e74705SXin Li int run = X{}.g();
1197*67e74705SXin Li
1198*67e74705SXin Li }
1199*67e74705SXin Li
1200*67e74705SXin Li
1201*67e74705SXin Li namespace nested_this_capture_3_2 {
1202*67e74705SXin Li struct X {
fnested_this_capture_3_2::X1203*67e74705SXin Li void f(int) { }
fnested_this_capture_3_2::X1204*67e74705SXin Li static void f(double) { }
1205*67e74705SXin Li
gnested_this_capture_3_2::X1206*67e74705SXin Li int g() {
1207*67e74705SXin Li auto L = [=](auto a) {
1208*67e74705SXin Li return [](int i) {
1209*67e74705SXin Li return [=](auto b) {
1210*67e74705SXin Li f(b); //expected-error {{'this' cannot}}
1211*67e74705SXin Li int x = i;
1212*67e74705SXin Li };
1213*67e74705SXin Li };
1214*67e74705SXin Li };
1215*67e74705SXin Li auto M = L(0.0);
1216*67e74705SXin Li auto N = M(3);
1217*67e74705SXin Li N(5); //expected-note {{in instantiation of}}
1218*67e74705SXin Li N(3.14); // OK.
1219*67e74705SXin Li return 0;
1220*67e74705SXin Li }
1221*67e74705SXin Li };
1222*67e74705SXin Li
1223*67e74705SXin Li int run = X{}.g();
1224*67e74705SXin Li
1225*67e74705SXin Li }
1226*67e74705SXin Li
1227*67e74705SXin Li namespace nested_this_capture_4 {
1228*67e74705SXin Li struct X {
fnested_this_capture_4::X1229*67e74705SXin Li void f(int) { }
fnested_this_capture_4::X1230*67e74705SXin Li static void f(double) { }
1231*67e74705SXin Li
gnested_this_capture_4::X1232*67e74705SXin Li int g() {
1233*67e74705SXin Li auto L = [](auto a) {
1234*67e74705SXin Li return [=](auto i) {
1235*67e74705SXin Li return [=](auto b) {
1236*67e74705SXin Li f(b); //expected-error {{'this' cannot}}
1237*67e74705SXin Li int x = i;
1238*67e74705SXin Li };
1239*67e74705SXin Li };
1240*67e74705SXin Li };
1241*67e74705SXin Li auto M = L(0.0);
1242*67e74705SXin Li auto N = M(3);
1243*67e74705SXin Li N(5); //expected-note {{in instantiation of}}
1244*67e74705SXin Li N(3.14); // OK.
1245*67e74705SXin Li return 0;
1246*67e74705SXin Li }
1247*67e74705SXin Li };
1248*67e74705SXin Li
1249*67e74705SXin Li int run = X{}.g();
1250*67e74705SXin Li
1251*67e74705SXin Li }
1252*67e74705SXin Li namespace capture_enclosing_function_parameters {
1253*67e74705SXin Li
1254*67e74705SXin Li
foo(int x)1255*67e74705SXin Li inline auto foo(int x) {
1256*67e74705SXin Li int i = 10;
1257*67e74705SXin Li auto lambda = [=](auto z) { return x + z; };
1258*67e74705SXin Li return lambda;
1259*67e74705SXin Li }
1260*67e74705SXin Li
foo2()1261*67e74705SXin Li int foo2() {
1262*67e74705SXin Li auto L = foo(3);
1263*67e74705SXin Li L(4);
1264*67e74705SXin Li L('a');
1265*67e74705SXin Li L(3.14);
1266*67e74705SXin Li return 0;
1267*67e74705SXin Li }
1268*67e74705SXin Li
foo3(int x)1269*67e74705SXin Li inline auto foo3(int x) {
1270*67e74705SXin Li int local = 1;
1271*67e74705SXin Li auto L = [=](auto a) {
1272*67e74705SXin Li int i = a[local];
1273*67e74705SXin Li return [=](auto b) mutable {
1274*67e74705SXin Li auto n = b;
1275*67e74705SXin Li return [&, n](auto c) mutable {
1276*67e74705SXin Li ++local;
1277*67e74705SXin Li return ++x;
1278*67e74705SXin Li };
1279*67e74705SXin Li };
1280*67e74705SXin Li };
1281*67e74705SXin Li auto M = L("foo-abc");
1282*67e74705SXin Li auto N = M("foo-def");
1283*67e74705SXin Li auto O = N("foo-ghi");
1284*67e74705SXin Li
1285*67e74705SXin Li return L;
1286*67e74705SXin Li }
1287*67e74705SXin Li
main()1288*67e74705SXin Li int main() {
1289*67e74705SXin Li auto L3 = foo3(3);
1290*67e74705SXin Li auto M3 = L3("L3-1");
1291*67e74705SXin Li auto N3 = M3("M3-1");
1292*67e74705SXin Li auto O3 = N3("N3-1");
1293*67e74705SXin Li N3("N3-2");
1294*67e74705SXin Li M3("M3-2");
1295*67e74705SXin Li M3("M3-3");
1296*67e74705SXin Li L3("L3-2");
1297*67e74705SXin Li }
1298*67e74705SXin Li } // end ns
1299*67e74705SXin Li
1300*67e74705SXin Li namespace capture_arrays {
1301*67e74705SXin Li
sum_array(int n)1302*67e74705SXin Li inline int sum_array(int n) {
1303*67e74705SXin Li int array2[5] = { 1, 2, 3, 4, 5};
1304*67e74705SXin Li
1305*67e74705SXin Li auto L = [=](auto N) -> int {
1306*67e74705SXin Li int sum = 0;
1307*67e74705SXin Li int array[5] = { 1, 2, 3, 4, 5 };
1308*67e74705SXin Li sum += array2[sum];
1309*67e74705SXin Li sum += array2[N];
1310*67e74705SXin Li return 0;
1311*67e74705SXin Li };
1312*67e74705SXin Li L(2);
1313*67e74705SXin Li return L(n);
1314*67e74705SXin Li }
1315*67e74705SXin Li }
1316*67e74705SXin Li
1317*67e74705SXin Li namespace capture_non_odr_used_variable_because_named_in_instantiation_dependent_expressions {
1318*67e74705SXin Li
1319*67e74705SXin Li // even though 'x' is not odr-used, it should be captured.
1320*67e74705SXin Li
test()1321*67e74705SXin Li int test() {
1322*67e74705SXin Li const int x = 10;
1323*67e74705SXin Li auto L = [=](auto a) {
1324*67e74705SXin Li (void) +x + a;
1325*67e74705SXin Li };
1326*67e74705SXin Li ASSERT_CLOSURE_SIZE_EXACT(L, sizeof(x));
1327*67e74705SXin Li }
1328*67e74705SXin Li
1329*67e74705SXin Li } //end ns
1330*67e74705SXin Li #ifdef MS_EXTENSIONS
1331*67e74705SXin Li namespace explicit_spec {
1332*67e74705SXin Li template<class R> struct X {
fooexplicit_spec::X1333*67e74705SXin Li template<class T> int foo(T t) {
1334*67e74705SXin Li auto L = [](auto a) { return a; };
1335*67e74705SXin Li L(&t);
1336*67e74705SXin Li return 0;
1337*67e74705SXin Li }
1338*67e74705SXin Li
fooexplicit_spec::X1339*67e74705SXin Li template<> int foo<char>(char c) { //expected-warning{{explicit specialization}}
1340*67e74705SXin Li const int x = 10;
1341*67e74705SXin Li auto LC = [](auto a) { return a; };
1342*67e74705SXin Li R r;
1343*67e74705SXin Li LC(&r);
1344*67e74705SXin Li auto L = [=](auto a) {
1345*67e74705SXin Li return [=](auto b) {
1346*67e74705SXin Li int d[sizeof(a)];
1347*67e74705SXin Li f(x, d);
1348*67e74705SXin Li };
1349*67e74705SXin Li };
1350*67e74705SXin Li auto M = L(1);
1351*67e74705SXin Li
1352*67e74705SXin Li ASSERT_NO_CAPTURES(M);
1353*67e74705SXin Li return 0;
1354*67e74705SXin Li }
1355*67e74705SXin Li
1356*67e74705SXin Li };
1357*67e74705SXin Li
1358*67e74705SXin Li int run_char = X<int>{}.foo('a');
1359*67e74705SXin Li int run_int = X<double>{}.foo(4);
1360*67e74705SXin Li }
1361*67e74705SXin Li #endif // MS_EXTENSIONS
1362*67e74705SXin Li
1363*67e74705SXin Li namespace nsdmi_capturing_this {
1364*67e74705SXin Li struct X {
1365*67e74705SXin Li int m = 10;
__anon59f5a0459f02nsdmi_capturing_this::X1366*67e74705SXin Li int n = [this](auto) { return m; }(20);
1367*67e74705SXin Li };
1368*67e74705SXin Li
1369*67e74705SXin Li template<class T>
1370*67e74705SXin Li struct XT {
1371*67e74705SXin Li T m = 10;
__anon59f5a045a002nsdmi_capturing_this::XT1372*67e74705SXin Li T n = [this](auto) { return m; }(20);
1373*67e74705SXin Li };
1374*67e74705SXin Li
1375*67e74705SXin Li XT<int> xt{};
1376*67e74705SXin Li
1377*67e74705SXin Li
1378*67e74705SXin Li }
1379