1 | // RUN: %clang_cc1 -std=c++1y %s -verify -emit-llvm-only |
2 | |
3 | namespace variadic_expansion { |
4 | int f(int &, char &) { return 0; } |
5 | template<class ... Ts> char fv(Ts ... ts) { return 0; } |
6 | // FIXME: why do we get 2 error messages |
7 | template <typename ... T> void g(T &... t) { //expected-note3{{declared here}} |
8 | f([&a(t)]()->decltype(auto) { |
9 | return a; |
10 | }() ...); |
11 | |
12 | auto L = [x = f([&a(t)]()->decltype(auto) { return a; }()...)]() { return x; }; |
13 | const int y = 10; |
14 | auto M = [x = y, |
15 | &z = y](T& ... t) { }; |
16 | auto N = [x = y, |
17 | &z = y, n = f(t...), |
18 | o = f([&a(t)](T& ... t)->decltype(auto) { return a; }(t...)...), t...](T& ... s) { |
19 | fv([&a(t)]()->decltype(auto) { |
20 | return a; |
21 | }() ...); |
22 | }; |
23 | auto N2 = [x = y, //expected-note3{{begins here}} |
24 | &z = y, n = f(t...), |
25 | o = f([&a(t)](T& ... t)->decltype(auto) { return a; }(t...)...)](T& ... s) { |
26 | fv([&a(t)]()->decltype(auto) { //expected-error 3{{captured}} |
27 | return a; |
28 | }() ...); |
29 | }; |
30 | |
31 | } |
32 | |
33 | void h(int i, char c) { g(i, c); } //expected-note{{in instantiation}} |
34 | } |
35 | |
36 | namespace odr_use_within_init_capture { |
37 | |
38 | int test() { |
39 | |
40 | { // no captures |
41 | const int x = 10; |
42 | auto L = [z = x + 2](int a) { |
43 | auto M = [y = x - 2](char b) { |
44 | return y; |
45 | }; |
46 | return M; |
47 | }; |
48 | |
49 | } |
50 | { // should not capture |
51 | const int x = 10; |
52 | auto L = [&z = x](int a) { |
53 | return a;; |
54 | }; |
55 | |
56 | } |
57 | { |
58 | const int x = 10; |
59 | auto L = [k = x](char a) { //expected-note {{declared}} |
60 | return [](int b) { //expected-note {{begins}} |
61 | return [j = k](int c) { //expected-error {{cannot be implicitly captured}} |
62 | return c; |
63 | }; |
64 | }; |
65 | }; |
66 | } |
67 | { |
68 | const int x = 10; |
69 | auto L = [k = x](char a) { |
70 | return [=](int b) { |
71 | return [j = k](int c) { |
72 | return c; |
73 | }; |
74 | }; |
75 | }; |
76 | } |
77 | { |
78 | const int x = 10; |
79 | auto L = [k = x](char a) { |
80 | return [k](int b) { |
81 | return [j = k](int c) { |
82 | return c; |
83 | }; |
84 | }; |
85 | }; |
86 | } |
87 | |
88 | return 0; |
89 | } |
90 | |
91 | int run = test(); |
92 | |
93 | } |
94 | |
95 | namespace odr_use_within_init_capture_template { |
96 | |
97 | template<class T = int> |
98 | int test(T t = T{}) { |
99 | |
100 | { // no captures |
101 | const T x = 10; |
102 | auto L = [z = x](char a) { |
103 | auto M = [y = x](T b) { |
104 | return y; |
105 | }; |
106 | return M; |
107 | }; |
108 | |
109 | } |
110 | { // should not capture |
111 | const T x = 10; |
112 | auto L = [&z = x](T a) { |
113 | return a;; |
114 | }; |
115 | |
116 | } |
117 | { // will need to capture x in outer lambda |
118 | const T x = 10; //expected-note {{declared}} |
119 | auto L = [z = x](char a) { //expected-note {{begins}} |
120 | auto M = [&y = x](T b) { //expected-error {{cannot be implicitly captured}} |
121 | return y; |
122 | }; |
123 | return M; |
124 | }; |
125 | |
126 | } |
127 | { // will need to capture x in outer lambda |
128 | const T x = 10; |
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; |
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}} |
148 | auto L = [z = x](char a) { //expected-note {{begins}} |
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 = |
159 | [z = x, &y = x](char a) { return z + y; }('a')](char a) |
160 | { return z; }; |
161 | |
162 | } |
163 | |
164 | return 0; |
165 | } |
166 | |
167 | int run = test(); //expected-note {{instantiation}} |
168 | |
169 | } |
170 | |
171 | namespace classification_of_captures_of_init_captures { |
172 | |
173 | template <typename T> |
174 | void f() { |
175 | [a = 24] () mutable { |
176 | [&a] { a = 3; }(); |
177 | }(); |
178 | } |
179 | |
180 | template <typename T> |
181 | void h() { |
182 | [a = 24] (auto param) mutable { |
183 | [&a] { a = 3; }(); |
184 | }(42); |
185 | } |
186 | |
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; }; |
196 | auto a = [x{X()}] { return x.n; }; // ok |
197 | auto b = [x = {X()}] {}; // expected-error{{<initializer_list>}} |
198 | } |
199 | |
200 | namespace init_capture_non_mutable { |
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 { |
211 | auto a = [x = y]{}; // expected-error{{use of undeclared identifier 'y'}} |
212 | |
213 | int typo_foo; // expected-note 2 {{'typo_foo' declared here}} |
214 | auto b = [x = typo_boo]{}; // expected-error{{use of undeclared identifier 'typo_boo'; did you mean 'typo_foo'}} |
215 | auto c = [x(typo_boo)]{}; // expected-error{{use of undeclared identifier 'typo_boo'; did you mean 'typo_foo'}} |
216 | } |
217 | |