xref: /minix3/external/bsd/llvm/dist/clang/test/SemaCXX/lambda-expressions.cpp (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -std=c++11 -Wno-unused-value -fsyntax-only -verify -fblocks %s
2*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -std=c++1y -Wno-unused-value -fsyntax-only -verify -fblocks %s
3*f4a2713aSLionel Sambuc 
4*f4a2713aSLionel Sambuc namespace std { class type_info; };
5*f4a2713aSLionel Sambuc 
6*f4a2713aSLionel Sambuc namespace ExplicitCapture {
7*f4a2713aSLionel Sambuc   class C {
8*f4a2713aSLionel Sambuc     int Member;
9*f4a2713aSLionel Sambuc 
10*f4a2713aSLionel Sambuc     static void Overload(int);
11*f4a2713aSLionel Sambuc     void Overload();
12*f4a2713aSLionel Sambuc     virtual C& Overload(float);
13*f4a2713aSLionel Sambuc 
14*f4a2713aSLionel Sambuc     void ImplicitThisCapture() {
15*f4a2713aSLionel Sambuc       [](){(void)Member;}; // expected-error {{'this' cannot be implicitly captured in this context}}
16*f4a2713aSLionel Sambuc       [&](){(void)Member;};
17*f4a2713aSLionel Sambuc 
18*f4a2713aSLionel Sambuc       [this](){(void)Member;};
19*f4a2713aSLionel Sambuc       [this]{[this]{};};
20*f4a2713aSLionel Sambuc       []{[this]{};};// expected-error {{'this' cannot be implicitly captured in this context}}
21*f4a2713aSLionel Sambuc       []{Overload(3);};
22*f4a2713aSLionel Sambuc       []{Overload();}; // expected-error {{'this' cannot be implicitly captured in this context}}
23*f4a2713aSLionel Sambuc       []{(void)typeid(Overload());};
24*f4a2713aSLionel Sambuc       []{(void)typeid(Overload(.5f));};// expected-error {{'this' cannot be implicitly captured in this context}}
25*f4a2713aSLionel Sambuc     }
26*f4a2713aSLionel Sambuc   };
27*f4a2713aSLionel Sambuc 
28*f4a2713aSLionel Sambuc   void f() {
29*f4a2713aSLionel Sambuc     [this] () {}; // expected-error {{'this' cannot be captured in this context}}
30*f4a2713aSLionel Sambuc   }
31*f4a2713aSLionel Sambuc }
32*f4a2713aSLionel Sambuc 
33*f4a2713aSLionel Sambuc namespace ReturnDeduction {
34*f4a2713aSLionel Sambuc   void test() {
35*f4a2713aSLionel Sambuc     [](){ return 1; };
36*f4a2713aSLionel Sambuc     [](){ return 1; };
37*f4a2713aSLionel Sambuc     [](){ return ({return 1; 1;}); };
38*f4a2713aSLionel Sambuc     [](){ return ({return 'c'; 1;}); }; // expected-error {{must match previous return type}}
39*f4a2713aSLionel Sambuc     []()->int{ return 'c'; return 1; };
40*f4a2713aSLionel Sambuc     [](){ return 'c'; return 1; };  // expected-error {{must match previous return type}}
41*f4a2713aSLionel Sambuc     []() { return; return (void)0; };
42*f4a2713aSLionel Sambuc     [](){ return 1; return 1; };
43*f4a2713aSLionel Sambuc   }
44*f4a2713aSLionel Sambuc }
45*f4a2713aSLionel Sambuc 
46*f4a2713aSLionel Sambuc namespace ImplicitCapture {
47*f4a2713aSLionel Sambuc   void test() {
48*f4a2713aSLionel Sambuc     int a = 0; // expected-note 5 {{declared}}
49*f4a2713aSLionel Sambuc     []() { return a; }; // expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{begins here}}
50*f4a2713aSLionel Sambuc     [&]() { return a; };
51*f4a2713aSLionel Sambuc     [=]() { return a; };
52*f4a2713aSLionel Sambuc     [=]() { int* b = &a; }; // expected-error {{cannot initialize a variable of type 'int *' with an rvalue of type 'const int *'}}
53*f4a2713aSLionel Sambuc     [=]() { return [&]() { return a; }; };
54*f4a2713aSLionel Sambuc     []() { return [&]() { return a; }; }; // expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}}
55*f4a2713aSLionel Sambuc     []() { return ^{ return a; }; };// expected-error {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}}
56*f4a2713aSLionel Sambuc     []() { return [&a] { return a; }; }; // expected-error 2 {{variable 'a' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note 2 {{lambda expression begins here}}
57*f4a2713aSLionel Sambuc     [=]() { return [&a] { return a; }; }; //
58*f4a2713aSLionel Sambuc 
59*f4a2713aSLionel Sambuc     const int b = 2;
60*f4a2713aSLionel Sambuc     []() { return b; };
61*f4a2713aSLionel Sambuc 
62*f4a2713aSLionel Sambuc     union { // expected-note {{declared}}
63*f4a2713aSLionel Sambuc       int c;
64*f4a2713aSLionel Sambuc       float d;
65*f4a2713aSLionel Sambuc     };
66*f4a2713aSLionel Sambuc     d = 3;
67*f4a2713aSLionel Sambuc     [=]() { return c; }; // expected-error {{unnamed variable cannot be implicitly captured in a lambda expression}}
68*f4a2713aSLionel Sambuc 
69*f4a2713aSLionel Sambuc     __block int e; // expected-note 3 {{declared}}
70*f4a2713aSLionel Sambuc     [&]() { return e; }; // expected-error {{__block variable 'e' cannot be captured in a lambda expression}}
71*f4a2713aSLionel Sambuc     [&e]() { return e; }; // expected-error 2 {{__block variable 'e' cannot be captured in a lambda expression}}
72*f4a2713aSLionel Sambuc 
73*f4a2713aSLionel Sambuc     int f[10]; // expected-note {{declared}}
74*f4a2713aSLionel Sambuc     [&]() { return f[2]; };
75*f4a2713aSLionel Sambuc     (void) ^{ return []() { return f[2]; }; }; // expected-error {{variable 'f' cannot be implicitly captured in a lambda with no capture-default specified}} \
76*f4a2713aSLionel Sambuc     // expected-note{{lambda expression begins here}}
77*f4a2713aSLionel Sambuc 
78*f4a2713aSLionel Sambuc     struct G { G(); G(G&); int a; }; // expected-note 6 {{not viable}}
79*f4a2713aSLionel Sambuc     G g;
80*f4a2713aSLionel Sambuc     [=]() { const G* gg = &g; return gg->a; };
81*f4a2713aSLionel Sambuc     [=]() { return [=]{ const G* gg = &g; return gg->a; }(); }; // expected-error {{no matching constructor for initialization of 'G'}}
82*f4a2713aSLionel Sambuc     (void)^{ return [=]{ const G* gg = &g; return gg->a; }(); }; // expected-error 2 {{no matching constructor for initialization of 'const G'}}
83*f4a2713aSLionel Sambuc 
84*f4a2713aSLionel Sambuc     const int h = a; // expected-note {{declared}}
85*f4a2713aSLionel Sambuc     []() { return h; }; // expected-error {{variable 'h' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}}
86*f4a2713aSLionel Sambuc 
87*f4a2713aSLionel Sambuc     // References can appear in constant expressions if they are initialized by
88*f4a2713aSLionel Sambuc     // reference constant expressions.
89*f4a2713aSLionel Sambuc     int i;
90*f4a2713aSLionel Sambuc     int &ref_i = i; // expected-note {{declared}}
91*f4a2713aSLionel Sambuc     [] { return ref_i; }; // expected-error {{variable 'ref_i' cannot be implicitly captured in a lambda with no capture-default specified}} expected-note {{lambda expression begins here}}
92*f4a2713aSLionel Sambuc 
93*f4a2713aSLionel Sambuc     static int j;
94*f4a2713aSLionel Sambuc     int &ref_j = j;
95*f4a2713aSLionel Sambuc     [] { return ref_j; }; // ok
96*f4a2713aSLionel Sambuc   }
97*f4a2713aSLionel Sambuc }
98*f4a2713aSLionel Sambuc 
99*f4a2713aSLionel Sambuc namespace PR12031 {
100*f4a2713aSLionel Sambuc   struct X {
101*f4a2713aSLionel Sambuc     template<typename T>
102*f4a2713aSLionel Sambuc     X(const T&);
103*f4a2713aSLionel Sambuc     ~X();
104*f4a2713aSLionel Sambuc   };
105*f4a2713aSLionel Sambuc 
106*f4a2713aSLionel Sambuc   void f(int i, X x);
107*f4a2713aSLionel Sambuc   void g() {
108*f4a2713aSLionel Sambuc     const int v = 10;
109*f4a2713aSLionel Sambuc     f(v, [](){});
110*f4a2713aSLionel Sambuc   }
111*f4a2713aSLionel Sambuc }
112*f4a2713aSLionel Sambuc 
113*f4a2713aSLionel Sambuc namespace Array {
114*f4a2713aSLionel Sambuc   int &f(int *p);
115*f4a2713aSLionel Sambuc   char &f(...);
116*f4a2713aSLionel Sambuc   void g() {
117*f4a2713aSLionel Sambuc     int n = -1;
118*f4a2713aSLionel Sambuc     [=] {
119*f4a2713aSLionel Sambuc       int arr[n]; // VLA
120*f4a2713aSLionel Sambuc     } ();
121*f4a2713aSLionel Sambuc 
122*f4a2713aSLionel Sambuc     const int m = -1;
123*f4a2713aSLionel Sambuc     [] {
124*f4a2713aSLionel Sambuc       int arr[m]; // expected-error{{negative size}}
125*f4a2713aSLionel Sambuc     } ();
126*f4a2713aSLionel Sambuc 
127*f4a2713aSLionel Sambuc     [&] {
128*f4a2713aSLionel Sambuc       int arr[m]; // expected-error{{negative size}}
129*f4a2713aSLionel Sambuc     } ();
130*f4a2713aSLionel Sambuc 
131*f4a2713aSLionel Sambuc     [=] {
132*f4a2713aSLionel Sambuc       int arr[m]; // expected-error{{negative size}}
133*f4a2713aSLionel Sambuc     } ();
134*f4a2713aSLionel Sambuc 
135*f4a2713aSLionel Sambuc     [m] {
136*f4a2713aSLionel Sambuc       int arr[m]; // expected-error{{negative size}}
137*f4a2713aSLionel Sambuc     } ();
138*f4a2713aSLionel Sambuc   }
139*f4a2713aSLionel Sambuc }
140*f4a2713aSLionel Sambuc 
141*f4a2713aSLionel Sambuc void PR12248()
142*f4a2713aSLionel Sambuc {
143*f4a2713aSLionel Sambuc   unsigned int result = 0;
144*f4a2713aSLionel Sambuc   auto l = [&]() { ++result; };
145*f4a2713aSLionel Sambuc }
146*f4a2713aSLionel Sambuc 
147*f4a2713aSLionel Sambuc namespace ModifyingCapture {
148*f4a2713aSLionel Sambuc   void test() {
149*f4a2713aSLionel Sambuc     int n = 0;
150*f4a2713aSLionel Sambuc     [=] {
151*f4a2713aSLionel Sambuc       n = 1; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}}
152*f4a2713aSLionel Sambuc     };
153*f4a2713aSLionel Sambuc   }
154*f4a2713aSLionel Sambuc }
155*f4a2713aSLionel Sambuc 
156*f4a2713aSLionel Sambuc namespace VariadicPackExpansion {
157*f4a2713aSLionel Sambuc   template<typename T, typename U> using Fst = T;
158*f4a2713aSLionel Sambuc   template<typename...Ts> bool g(Fst<bool, Ts> ...bools);
159*f4a2713aSLionel Sambuc   template<typename...Ts> bool f(Ts &&...ts) {
160*f4a2713aSLionel Sambuc     return g<Ts...>([&ts] {
161*f4a2713aSLionel Sambuc       if (!ts)
162*f4a2713aSLionel Sambuc         return false;
163*f4a2713aSLionel Sambuc       --ts;
164*f4a2713aSLionel Sambuc       return true;
165*f4a2713aSLionel Sambuc     } () ...);
166*f4a2713aSLionel Sambuc   }
167*f4a2713aSLionel Sambuc   void h() {
168*f4a2713aSLionel Sambuc     int a = 5, b = 2, c = 3;
169*f4a2713aSLionel Sambuc     while (f(a, b, c)) {
170*f4a2713aSLionel Sambuc     }
171*f4a2713aSLionel Sambuc   }
172*f4a2713aSLionel Sambuc 
173*f4a2713aSLionel Sambuc   struct sink {
174*f4a2713aSLionel Sambuc     template<typename...Ts> sink(Ts &&...) {}
175*f4a2713aSLionel Sambuc   };
176*f4a2713aSLionel Sambuc 
177*f4a2713aSLionel Sambuc   template<typename...Ts> void local_class() {
178*f4a2713aSLionel Sambuc     sink {
179*f4a2713aSLionel Sambuc       [] (Ts t) {
180*f4a2713aSLionel Sambuc         struct S : Ts {
181*f4a2713aSLionel Sambuc           void f(Ts t) {
182*f4a2713aSLionel Sambuc             Ts &that = *this;
183*f4a2713aSLionel Sambuc             that = t;
184*f4a2713aSLionel Sambuc           }
185*f4a2713aSLionel Sambuc           Ts g() { return *this; };
186*f4a2713aSLionel Sambuc         };
187*f4a2713aSLionel Sambuc         S s;
188*f4a2713aSLionel Sambuc         s.f(t);
189*f4a2713aSLionel Sambuc         return s;
190*f4a2713aSLionel Sambuc       } (Ts()).g() ...
191*f4a2713aSLionel Sambuc     };
192*f4a2713aSLionel Sambuc   };
193*f4a2713aSLionel Sambuc   struct X {}; struct Y {};
194*f4a2713aSLionel Sambuc   template void local_class<X, Y>();
195*f4a2713aSLionel Sambuc 
196*f4a2713aSLionel Sambuc   template<typename...Ts> void nested(Ts ...ts) {
197*f4a2713aSLionel Sambuc     f(
198*f4a2713aSLionel Sambuc       // Each expansion of this lambda implicitly captures all of 'ts', because
199*f4a2713aSLionel Sambuc       // the inner lambda also expands 'ts'.
200*f4a2713aSLionel Sambuc       [&] {
201*f4a2713aSLionel Sambuc         return ts + [&] { return f(ts...); } ();
202*f4a2713aSLionel Sambuc       } () ...
203*f4a2713aSLionel Sambuc     );
204*f4a2713aSLionel Sambuc   }
205*f4a2713aSLionel Sambuc   template void nested(int, int, int);
206*f4a2713aSLionel Sambuc 
207*f4a2713aSLionel Sambuc   template<typename...Ts> void nested2(Ts ...ts) { // expected-note 2{{here}}
208*f4a2713aSLionel Sambuc     // Capture all 'ts', use only one.
209*f4a2713aSLionel Sambuc     f([&ts...] { return ts; } ()...);
210*f4a2713aSLionel Sambuc     // Capture each 'ts', use it.
211*f4a2713aSLionel Sambuc     f([&ts] { return ts; } ()...);
212*f4a2713aSLionel Sambuc     // Capture all 'ts', use all of them.
213*f4a2713aSLionel Sambuc     f([&ts...] { return (int)f(ts...); } ());
214*f4a2713aSLionel Sambuc     // Capture each 'ts', use all of them. Ill-formed. In more detail:
215*f4a2713aSLionel Sambuc     //
216*f4a2713aSLionel Sambuc     // We instantiate two lambdas here; the first captures ts$0, the second
217*f4a2713aSLionel Sambuc     // captures ts$1. Both of them reference both ts parameters, so both are
218*f4a2713aSLionel Sambuc     // ill-formed because ts can't be implicitly captured.
219*f4a2713aSLionel Sambuc     //
220*f4a2713aSLionel Sambuc     // FIXME: This diagnostic does not explain what's happening. We should
221*f4a2713aSLionel Sambuc     // specify which 'ts' we're referring to in its diagnostic name. We should
222*f4a2713aSLionel Sambuc     // also say which slice of the pack expansion is being performed in the
223*f4a2713aSLionel Sambuc     // instantiation backtrace.
224*f4a2713aSLionel Sambuc     f([&ts] { return (int)f(ts...); } ()...); // \
225*f4a2713aSLionel Sambuc     // expected-error 2{{'ts' cannot be implicitly captured}} \
226*f4a2713aSLionel Sambuc     // expected-note 2{{lambda expression begins here}}
227*f4a2713aSLionel Sambuc   }
228*f4a2713aSLionel Sambuc   template void nested2(int); // ok
229*f4a2713aSLionel Sambuc   template void nested2(int, int); // expected-note {{in instantiation of}}
230*f4a2713aSLionel Sambuc }
231*f4a2713aSLionel Sambuc 
232*f4a2713aSLionel Sambuc namespace PR13860 {
233*f4a2713aSLionel Sambuc   void foo() {
234*f4a2713aSLionel Sambuc     auto x = PR13860UndeclaredIdentifier(); // expected-error {{use of undeclared identifier 'PR13860UndeclaredIdentifier'}}
235*f4a2713aSLionel Sambuc     auto y = [x]() { };
236*f4a2713aSLionel Sambuc     static_assert(sizeof(y), "");
237*f4a2713aSLionel Sambuc   }
238*f4a2713aSLionel Sambuc }
239*f4a2713aSLionel Sambuc 
240*f4a2713aSLionel Sambuc namespace PR13854 {
241*f4a2713aSLionel Sambuc   auto l = [](void){};
242*f4a2713aSLionel Sambuc }
243*f4a2713aSLionel Sambuc 
244*f4a2713aSLionel Sambuc namespace PR14518 {
245*f4a2713aSLionel Sambuc   auto f = [](void) { return __func__; }; // no-warning
246*f4a2713aSLionel Sambuc }
247*f4a2713aSLionel Sambuc 
248*f4a2713aSLionel Sambuc namespace PR16708 {
249*f4a2713aSLionel Sambuc   auto L = []() {
250*f4a2713aSLionel Sambuc     auto ret = 0;
251*f4a2713aSLionel Sambuc     return ret;
252*f4a2713aSLionel Sambuc     return 0;
253*f4a2713aSLionel Sambuc   };
254*f4a2713aSLionel Sambuc }
255*f4a2713aSLionel Sambuc 
256*f4a2713aSLionel Sambuc namespace TypeDeduction {
257*f4a2713aSLionel Sambuc   struct S {};
258*f4a2713aSLionel Sambuc   void f() {
259*f4a2713aSLionel Sambuc     const S s {};
260*f4a2713aSLionel Sambuc     S &&t = [&] { return s; } ();
261*f4a2713aSLionel Sambuc #if __cplusplus <= 201103L
262*f4a2713aSLionel Sambuc     // expected-error@-2 {{drops qualifiers}}
263*f4a2713aSLionel Sambuc #else
264*f4a2713aSLionel Sambuc     S &&u = [&] () -> auto { return s; } ();
265*f4a2713aSLionel Sambuc #endif
266*f4a2713aSLionel Sambuc   }
267*f4a2713aSLionel Sambuc }
268*f4a2713aSLionel Sambuc 
269*f4a2713aSLionel Sambuc 
270*f4a2713aSLionel Sambuc namespace lambdas_in_NSDMIs {
271*f4a2713aSLionel Sambuc   template<class T>
272*f4a2713aSLionel Sambuc   struct L {
273*f4a2713aSLionel Sambuc       T t{};
274*f4a2713aSLionel Sambuc       T t2 = ([](int a) { return [](int b) { return b; };})(t)(t);
275*f4a2713aSLionel Sambuc   };
276*f4a2713aSLionel Sambuc   L<int> l;
277*f4a2713aSLionel Sambuc 
278*f4a2713aSLionel Sambuc   namespace non_template {
279*f4a2713aSLionel Sambuc     struct L {
280*f4a2713aSLionel Sambuc       int t = 0;
281*f4a2713aSLionel Sambuc       int t2 = ([](int a) { return [](int b) { return b; };})(t)(t);
282*f4a2713aSLionel Sambuc     };
283*f4a2713aSLionel Sambuc     L l;
284*f4a2713aSLionel Sambuc   }
285*f4a2713aSLionel Sambuc }