Clang Project

clang_source_code/test/SemaCXX/cxx1y-init-captures.cpp
1// RUN: %clang_cc1 -std=c++1y %s -verify -emit-llvm-only
2
3namespace 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
36namespace odr_use_within_init_capture {
37
38int 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
91int run = test();
92
93}
94
95namespace odr_use_within_init_capture_template {
96
97template<class T = int>
98int 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
167int run = test(); //expected-note {{instantiation}}
168
169}
170
171namespace classification_of_captures_of_init_captures {
172
173template <typename T>
174void f() {
175  [a = 24] () mutable {
176    [&a] { a = 3; }();
177  }();
178}
179
180template <typename T>
181void h() {
182  [a = 24] (auto param) mutable {
183    [&a] { a = 3; }();
184  }(42);
185}
186
187int run() {
188  f<int>();
189  h<int>();
190}
191
192}
193
194namespace 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
200namespace init_capture_non_mutable {
201void 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
210namespace 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