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