xref: /llvm-project/clang/test/SemaCXX/cxx1y-init-captures.cpp (revision 3eeed79946124a8f67a89bb950a1e510369dcdf9)
1 // RUN: %clang_cc1 -std=c++1y %s -verify -emit-llvm-only
2 // RUN: %clang_cc1 -std=c++1z %s -verify -emit-llvm-only
3 
4 namespace variadic_expansion {
f(int &,char &)5   int f(int &, char &) { return 0; }
fv(Ts...ts)6   template<class ... Ts> char fv(Ts ... ts) { return 0; }
7   // FIXME: why do we get 2 error messages
g(T &...t)8   template <typename ... T> void g(T &... t) { //expected-note3{{declared here}}
9     f([&a(t)]()->decltype(auto) {
10       return a;
11     }() ...);
12 
13     auto L = [x = f([&a(t)]()->decltype(auto) { return a; }()...)]() { return x; };
14     const int y = 10;
15     auto M = [x = y,
16                 &z = y](T& ... t) { };
17     auto N = [x = y,
18                 &z = y, n = f(t...),
19                 o = f([&a(t)](T& ... t)->decltype(auto) { return a; }(t...)...), t...](T& ... s) {
20                   fv([&a(t)]()->decltype(auto) {
21                     return a;
22                   }() ...);
23                 };
24     auto N2 = [x = y, //expected-note3{{begins here}} expected-note 6 {{default capture by}}
25                 &z = y, n = f(t...),
26                 o = f([&a(t)](T& ... t)->decltype(auto) { return a; }(t...)...)](T& ... s) { // expected-note 6 {{capture 't' by}} expected-note {{substituting into a lambda}}
27                 fv([&a(t)]()->decltype(auto) { //expected-error 3{{captured}}
28                     return a;
29                   }() ...);
30                 };
31 
32   }
33 
h(int i,char c)34   void h(int i, char c) { g(i, c); } // expected-note {{requested here}}
35 }
36 
37 namespace odr_use_within_init_capture {
38 
test()39 int test() {
40 
41   { // no captures
42     const int x = 10;
43     auto L = [z = x + 2](int a) {
44       auto M = [y = x - 2](char b) {
45         return y;
46       };
47       return M;
48     };
49 
50   }
51   { // should not capture
52     const int x = 10;
53     auto L = [&z = x](int a) {
54       return a;;
55     };
56 
57   }
58   {
59     const int x = 10;
60     auto L = [k = x](char a) {  //expected-note {{declared}}
61       return [](int b) {        //expected-note {{begins}} expected-note 2 {{capture 'k' by}} expected-note 2 {{default capture by}}
62         return [j = k](int c) { //expected-error {{cannot be implicitly captured}}
63           return c;
64         };
65       };
66     };
67   }
68   {
69     const int x = 10;
70     auto L = [k = x](char a) {
71       return [=](int b) {
72         return [j = k](int c) {
73           return c;
74         };
75       };
76     };
77   }
78   {
79     const int x = 10;
80     auto L = [k = x](char a) {
81       return [k](int b) {
82         return [j = k](int c) {
83           return c;
84         };
85       };
86     };
87   }
88 
89   return 0;
90 }
91 
92 int run = test();
93 
94 }
95 
96 namespace odr_use_within_init_capture_template {
97 
98 template<class T = int>
test(T t=T{})99 int test(T t = T{}) {
100 
101   { // no captures
102     const T x = 10;
__anonc26aba101102(char a) 103     auto L = [z = x](char a) {
104       auto M = [y = x](T b) {
105         return y;
106       };
107       return M;
108     };
109 
110   }
111   { // should not capture
112     const T x = 10;
__anonc26aba101302(T a) 113     auto L = [&z = x](T a) {
114       return a;;
115     };
116 
117   }
118   { // will need to capture x in outer lambda
119     const T x = 10; //expected-note {{declared}}
__anonc26aba101402(char a) 120     auto L = [z = x](char a) { //expected-note {{begins}} expected-note 2 {{capture 'x' by}} expected-note 2 {{default capture by}} expected-note {{substituting into a lambda}}
121       auto M = [&y = x](T b) { //expected-error {{cannot be implicitly captured}}
122         return y;
123       };
124       return M;
125     };
126   }
127   { // will need to capture x in outer lambda
128     const T x = 10;
__anonc26aba101602(char a) 129     auto L = [=,z = x](char a) {
130       auto M = [&y = x](T b) {
131         return y;
132       };
133       return M;
134     };
135 
136   }
137   { // will need to capture x in outer lambda
138     const T x = 10;
__anonc26aba101802(char a) 139     auto L = [x, z = x](char a) {
140       auto M = [&y = x](T b) {
141         return y;
142       };
143       return M;
144     };
145   }
146   { // will need to capture x in outer lambda
147     const int x = 10; //expected-note {{declared}}
__anonc26aba101a02(char a) 148     auto L = [z = x](char a) { //expected-note {{begins}} expected-note 2 {{capture 'x' by}} expected-note 2 {{default capture by}} expected-note {{substituting into a lambda}}
149       auto M = [&y = x](T b) { //expected-error {{cannot be implicitly captured}}
150         return y;
151       };
152       return M;
153     };
154   }
155   {
156     // no captures
157     const T x = 10;
158     auto L = [z =
__anonc26aba101c02(char a) 159                   [z = x, &y = x](char a) { return z + y; }('a')](char a)
__anonc26aba101d02(char a) 160       { return z; };
161 
162   }
163 
164   return 0;
165 }
166 
167 int run = test(); //expected-note 2 {{instantiation}}
168 
169 }
170 
171 namespace classification_of_captures_of_init_captures {
172 
173 template <typename T>
f()174 void f() {
175   [a = 24] () mutable {
176     [&a] { a = 3; }();
177   }();
178 }
179 
180 template <typename T>
h()181 void h() {
182   [a = 24] (auto param) mutable {
183     [&a] { a = 3; }();
184   }(42);
185 }
186 
run()187 int run() {
188   f<int>();
189   h<int>();
190 }
191 
192 }
193 
194 namespace N3922 {
195   struct X { X(); explicit X(const X&); int n; };
__anonc26aba102202null196   auto a = [x{X()}] { return x.n; }; // ok
__anonc26aba102302null197   auto b = [x = {X()}] {}; // expected-error{{<initializer_list>}}
198 }
199 
200 namespace init_capture_non_mutable {
test(double weight)201 void test(double weight) {
202   double init;
203   auto find = [max = init](auto current) {
204     max = current; // expected-error{{cannot assign to a variable captured by copy in a non-mutable lambda}}
205   };
206   find(weight); // expected-note {{in instantiation of function template specialization}}
207 }
208 }
209 
210 namespace init_capture_undeclared_identifier {
__anonc26aba102502null211   auto a = [x = y]{}; // expected-error{{use of undeclared identifier 'y'}}
212 
213   int typo_foo; // expected-note 2 {{'typo_foo' declared here}}
__anonc26aba102602null214   auto b = [x = typo_boo]{}; // expected-error{{use of undeclared identifier 'typo_boo'; did you mean 'typo_foo'}}
__anonc26aba102702null215   auto c = [x(typo_boo)]{}; // expected-error{{use of undeclared identifier 'typo_boo'; did you mean 'typo_foo'}}
216 }
217 
218 namespace copy_evasion {
219   struct A {
220     A();
221     A(const A&) = delete;
222   };
__anonc26aba102802null223   auto x = [a{A()}] {};
224 #if __cplusplus >= 201702L
225   // ok, does not copy an 'A'
226 #else
227   // expected-error@-4 {{call to deleted}}
228   // expected-note@-7 {{deleted}}
229 #endif
230 }
231