cxx1y-generic-lambdas.cpp revision 618c28547a7f7cc785a6c6301f79febf5a584f9e
1// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -emit-llvm -o - %s
2// DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING
3// DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fms-extensions %s -DMS_EXTENSIONS
4// DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING
5
6namespace explicit_call {
7int test() {
8  auto L = [](auto a) { return a; };
9  L.operator()(3);
10  L.operator()<char>(3.14); //expected-warning{{implicit conversion}}
11  return 0;
12}
13} //end ns
14
15namespace test_conversion_to_fptr {
16
17void f1(int (*)(int)) { }
18void f2(char (*)(int)) { } // expected-note{{candidate}}
19void g(int (*)(int)) { } // #1 expected-note{{candidate}}
20void g(char (*)(char)) { } // #2 expected-note{{candidate}}
21void h(int (*)(int)) { } // #3
22void h(char (*)(int)) { } // #4
23
24int test() {
25{
26  auto glambda = [](auto a) { return a; };
27  glambda(1);
28  f1(glambda); // OK
29  f2(glambda); // expected-error{{no matching function}}
30  g(glambda); // expected-error{{call to 'g' is ambiguous}}
31  h(glambda); // OK: calls #3 since it is convertible from ID
32
33  int& (*fpi)(int*) = [](auto* a) -> auto& { return *a; }; // OK
34
35}
36{
37
38  auto L = [](auto a) { return a; };
39  int (*fp)(int) = L;
40  fp(5);
41  L(3);
42  char (*fc)(char) = L;
43  fc('b');
44  L('c');
45  double (*fd)(double) = L;
46  fd(3.14);
47  fd(6.26);
48  L(4.25);
49}
50{
51  auto L = [](auto a) ->int { return a; }; //expected-note 2{{candidate template ignored}}
52  int (*fp)(int) = L;
53  char (*fc)(char) = L; //expected-error{{no viable conversion}}
54  double (*fd)(double) = L; //expected-error{{no viable conversion}}
55}
56
57}
58
59namespace more_converion_to_ptr_to_function_tests {
60
61
62int test() {
63  {
64    int& (*fpi)(int*) = [](auto* a) -> auto& { return *a; }; // OK
65    int (*fp2)(int) = [](auto b) -> int {  return b; };
66    int (*fp3)(char) = [](auto c) -> int { return c; };
67    char (*fp4)(int) = [](auto d) { return d; }; //expected-error{{no viable conversion}}\
68                                                 //expected-note{{candidate template ignored}}
69    char (*fp5)(char) = [](auto e) -> int { return e; }; //expected-error{{no viable conversion}}\
70                                                 //expected-note{{candidate template ignored}}
71
72    fp2(3);
73    fp3('\n');
74    fp3('a');
75    return 0;
76  }
77} // end test()
78
79template<class ... Ts> void vfun(Ts ... ) { }
80
81int variadic_test() {
82
83 int (*fp)(int, char, double) = [](auto ... a) -> int { vfun(a...); return 4; };
84 fp(3, '4', 3.14);
85
86 int (*fp2)(int, char, double) = [](auto ... a) { vfun(a...); return 4; };
87 fp(3, '4', 3.14);
88 return 2;
89}
90
91} // end ns
92
93namespace conversion_operator {
94void test() {
95    auto L = [](auto a) -> int { return a; };
96    int (*fp)(int) = L;
97    int (&fp2)(int) = [](auto a) { return a; };  // expected-error{{non-const lvalue}}
98    int (&&fp3)(int) = [](auto a) { return a; };  // expected-error{{no viable conversion}}\
99                                                  //expected-note{{candidate}}
100  }
101}
102}
103
104namespace return_type_deduction_ok {
105 auto l = [](auto a) ->auto { return a; }(2);
106 auto l2 = [](auto a) ->decltype(auto) { return a; }(2);
107 auto l3 = [](auto a) { return a; }(2);
108
109}
110
111namespace generic_lambda_as_default_argument_ok {
112  void test(int i = [](auto a)->int { return a; }(3)) {
113  }
114}
115
116namespace nested_non_capturing_lambda_tests {
117template<class ... Ts> void print(Ts ...) { }
118int test() {
119{
120  auto L = [](auto a) {
121    return [](auto b) {
122      return b;
123    };
124  };
125  auto M = L(3);
126  M(4.15);
127 }
128{
129  int i = 10; //expected-note{{declared here}}
130  auto L = [](auto a) {
131    return [](auto b) { //expected-note{{begins here}}
132      i = b;  //expected-error{{cannot be implicitly captured}}
133      return b;
134    };
135  };
136  auto M = L(3);
137  M(4.15); //expected-note{{instantiation}}
138 }
139 {
140  auto L = [](auto a) {
141    print("a = ", a, "\n");
142    return [](auto b) ->decltype(a) {
143      print("b = ", b, "\n");
144      return b;
145    };
146  };
147  auto M = L(3);
148  M(4.15);
149 }
150
151{
152  auto L = [](auto a) ->decltype(a) {
153    print("a = ", a, "\n");
154    return [](auto b) ->decltype(a) { //expected-error{{no viable conversion}}\
155                                      //expected-note{{candidate template ignored}}
156      print("b = ", b, "\n");
157      return b;
158    };
159  };
160  auto M = L(3); //expected-note{{in instantiation of}}
161 }
162{
163  auto L = [](auto a) {
164    print("a = ", a, "\n");
165    return [](auto ... b) ->decltype(a) {
166      print("b = ", b ..., "\n");
167      return 4;
168    };
169  };
170  auto M = L(3);
171  M(4.15, 3, "fv");
172}
173
174{
175  auto L = [](auto a) {
176    print("a = ", a, "\n");
177    return [](auto ... b) ->decltype(a) {
178      print("b = ", b ..., "\n");
179      return 4;
180    };
181  };
182  auto M = L(3);
183  int (*fp)(double, int, const char*) = M;
184  fp(4.15, 3, "fv");
185}
186
187{
188  auto L = [](auto a) {
189    print("a = ", a, "\n");
190    return [](char b) {
191      return [](auto ... c) ->decltype(b) {
192        print("c = ", c ..., "\n");
193        return 42;
194      };
195    };
196  };
197  L(4);
198  auto M = L(3);
199  M('a');
200  auto N = M('x');
201  N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
202  char (*np)(const char*, int, const char*, double, const char*, int) = N;
203  np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
204}
205
206
207{
208  auto L = [](auto a) {
209    print("a = ", a, "\n");
210    return [](decltype(a) b) {
211      return [](auto ... c) ->decltype(b) {
212        print("c = ", c ..., "\n");
213        return 42;
214      };
215    };
216  };
217  L('4');
218  auto M = L('3');
219  M('a');
220  auto N = M('x');
221  N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
222  char (*np)(const char*, int, const char*, double, const char*, int) = N;
223  np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
224}
225
226
227{
228 struct X {
229  static void foo(double d) { }
230  void test() {
231    auto L = [](auto a) {
232      print("a = ", a, "\n");
233      foo(a);
234      return [](decltype(a) b) {
235        foo(b);
236        foo(sizeof(a) + sizeof(b));
237        return [](auto ... c) ->decltype(b) {
238          print("c = ", c ..., "\n");
239          foo(decltype(b){});
240          foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
241          return 42;
242        };
243      };
244    };
245    L('4');
246    auto M = L('3');
247    M('a');
248    auto N = M('x');
249    N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
250    char (*np)(const char*, int, const char*, double, const char*, int) = N;
251    np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
252  }
253};
254X x;
255x.test();
256}
257// Make sure we can escape the function
258{
259 struct X {
260  static void foo(double d) { }
261  auto test() {
262    auto L = [](auto a) {
263      print("a = ", a, "\n");
264      foo(a);
265      return [](decltype(a) b) {
266        foo(b);
267        foo(sizeof(a) + sizeof(b));
268        return [](auto ... c) ->decltype(b) {
269          print("c = ", c ..., "\n");
270          foo(decltype(b){});
271          foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
272          return 42;
273        };
274      };
275    };
276    return L;
277  }
278};
279  X x;
280  auto L = x.test();
281  L('4');
282  auto M = L('3');
283  M('a');
284  auto N = M('x');
285  N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
286  char (*np)(const char*, int, const char*, double, const char*, int) = N;
287  np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
288}
289
290{
291 struct X {
292  static void foo(double d) { }
293  auto test() {
294    auto L = [](auto a) {
295      print("a = ", a, "\n");
296      foo(a);
297      return [](decltype(a) b) {
298        foo(b);
299        foo(sizeof(a) + sizeof(b));
300        return [](auto ... c) {
301          print("c = ", c ..., "\n");
302          foo(decltype(b){});
303          foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
304          return [](decltype(c) ... d) ->decltype(a) { //expected-note{{candidate}}
305            print("d = ", d ..., "\n");
306            foo(decltype(b){});
307            foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
308            return decltype(a){};
309          };
310        };
311      };
312    };
313    return L;
314  }
315};
316  X x;
317  auto L = x.test();
318  L('4');
319  auto M = L('3');
320  M('a');
321  auto N = M('x');
322  auto O = N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
323  char (*np)(const char*, int, const char*, double, const char*, int) = O;
324  np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
325  int (*np2)(const char*, int, const char*, double, const char*, int) = O; // expected-error{{no viable conversion}}
326
327}
328} // end test()
329
330namespace wrapped_within_templates {
331
332namespace explicit_return {
333template<class T> int fooT(T t) {
334  auto L = [](auto a) -> void {
335    auto M = [](char b) -> void {
336      auto N = [](auto c) -> void {
337        int x = 0;
338        x = sizeof(a);
339        x = sizeof(b);
340        x = sizeof(c);
341      };
342      N('a');
343      N(decltype(a){});
344    };
345  };
346  L(t);
347  L(3.14);
348  return 0;
349}
350
351int run = fooT('a') + fooT(3.14);
352
353} // end explicit_return
354
355namespace implicit_return_deduction {
356template<class T> auto fooT(T t) {
357  auto L = [](auto a)  {
358    auto M = [](char b)  {
359      auto N = [](auto c)  {
360        int x = 0;
361        x = sizeof(a);
362        x = sizeof(b);
363        x = sizeof(c);
364      };
365      N('a');
366      N(decltype(a){});
367    };
368  };
369  L(t);
370  L(3.14);
371  return 0;
372}
373
374int run = fooT('a') + fooT(3.14);
375
376template<class ... Ts> void print(Ts ... ts) { }
377
378template<class F, class ... Rest> using first = F;
379
380template<class ... Ts> auto fooV(Ts ... ts) {
381  auto L = [](auto ... a) {
382    auto M = [](decltype(a) ... b) {
383      auto N = [](auto c) {
384        int x = 0;
385        x = sizeof...(a);
386        x = sizeof...(b);
387        x = sizeof(c);
388      };
389      N('a');
390      N(N);
391      N(first<Ts...>{});
392    };
393    M(a...);
394    print("a = ", a..., "\n");
395  };
396  L(L, ts...);
397  print("ts = ", ts..., "\n");
398  return 0;
399}
400
401int run2 = fooV(3.14, " ", '4', 5) + fooV("BC", 3, 2.77, 'A', float{}, short{}, unsigned{});
402
403} //implicit_return_deduction
404
405
406} //wrapped_within_templates
407
408namespace at_ns_scope {
409  void foo(double d) { }
410  auto test() {
411    auto L = [](auto a) {
412      print("a = ", a, "\n");
413      foo(a);
414      return [](decltype(a) b) {
415        foo(b);
416        foo(sizeof(a) + sizeof(b));
417        return [](auto ... c) {
418          print("c = ", c ..., "\n");
419          foo(decltype(b){});
420          foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
421          return [](decltype(c) ... d) ->decltype(a) { //expected-note{{candidate}}
422            print("d = ", d ..., "\n");
423            foo(decltype(b){});
424            foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
425            return decltype(a){};
426          };
427        };
428      };
429    };
430    return L;
431  }
432auto L = test();
433auto L_test = L('4');
434auto M = L('3');
435auto M_test = M('a');
436auto N = M('x');
437auto O = N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
438char (*np)(const char*, int, const char*, double, const char*, int) = O;
439auto NP_result = np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
440int (*np2)(const char*, int, const char*, double, const char*, int) = O; // expected-error{{no viable conversion}}
441
442
443
444}
445
446namespace variadic_tests_1 {
447template<class ... Ts> void print(Ts ... ts) { }
448
449template<class F, class ... Rest> using FirstType = F;
450template<class F, class ... Rest> F& FirstArg(F& f, Rest...) { return f; }
451
452template<class ... Ts> int fooV(Ts ... ts) {
453  auto L = [](auto ... a) -> void {
454    auto M = [](decltype(a) ... b) -> void {
455      auto N = [](auto c) -> void {
456        int x = 0;
457        x = sizeof...(a);
458        x = sizeof...(b);
459        x = sizeof(c);
460      };
461      N('a');
462      N(N);
463      N(FirstType<Ts...>{});
464    };
465    M(a...);
466    print("a = ", a..., "\n");
467  };
468  L(L, ts...);
469  print("ts = ", ts..., "\n");
470  return 0;
471}
472
473int run2 = fooV(3.14, " ", '4', 5) + fooV("BC", 3, 2.77, 'A', float{}, short{}, unsigned{});
474
475namespace more_variadic_1 {
476
477template<class ... Ts> int fooV(Ts ... ts) {
478  auto L = [](auto ... a) {
479    auto M = [](decltype(a) ... b) -> void {
480      auto N = [](auto c) -> void {
481        int x = 0;
482        x = sizeof...(a);
483        x = sizeof...(b);
484        x = sizeof(c);
485      };
486      N('a');
487      N(N);
488      N(FirstType<Ts...>{});
489    };
490    M(a...);
491    return M;
492  };
493  auto M = L(L, ts...);
494  decltype(L(L, ts...)) (*fp)(decltype(L), decltype(ts) ...) = L;
495  void (*fp2)(decltype(L), decltype(ts) ...) = L(L, ts...);
496
497  {
498    auto L = [](auto ... a) {
499      auto M = [](decltype(a) ... b) {
500        auto N = [](auto c) -> void {
501          int x = 0;
502          x = sizeof...(a);
503          x = sizeof...(b);
504          x = sizeof(c);
505        };
506        N('a');
507        N(N);
508        N(FirstType<Ts...>{});
509        return N;
510      };
511      M(a...);
512      return M;
513    };
514    auto M = L(L, ts...);
515    decltype(L(L, ts...)) (*fp)(decltype(L), decltype(ts) ...) = L;
516    fp(L, ts...);
517    decltype(L(L, ts...)(L, ts...)) (*fp2)(decltype(L), decltype(ts) ...) = L(L, ts...);
518    fp2 = fp(L, ts...);
519    void (*fp3)(char) = fp2(L, ts...);
520    fp3('a');
521  }
522  return 0;
523}
524
525int run2 = fooV(3.14, " ", '4', 5) + fooV("BC", 3, 2.77, 'A', float{}, short{}, unsigned{});
526
527
528} //end ns more_variadic_1
529
530} // end ns variadic_tests_1
531
532namespace at_ns_scope_within_class_member {
533 struct X {
534  static void foo(double d) { }
535  auto test() {
536    auto L = [](auto a) {
537      print("a = ", a, "\n");
538      foo(a);
539      return [](decltype(a) b) {
540        foo(b);
541        foo(sizeof(a) + sizeof(b));
542        return [](auto ... c) {
543          print("c = ", c ..., "\n");
544          foo(decltype(b){});
545          foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
546          return [](decltype(c) ... d) ->decltype(a) { //expected-note{{candidate}}
547            print("d = ", d ..., "\n");
548            foo(decltype(b){});
549            foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
550            return decltype(a){};
551          };
552        };
553      };
554    };
555    return L;
556  }
557};
558X x;
559auto L = x.test();
560auto L_test = L('4');
561auto M = L('3');
562auto M_test = M('a');
563auto N = M('x');
564auto O = N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
565char (*np)(const char*, int, const char*, double, const char*, int) = O;
566auto NP_result = np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
567int (*np2)(const char*, int, const char*, double, const char*, int) = O; // expected-error{{no viable conversion}}
568
569} //end at_ns_scope_within_class_member
570
571
572namespace nested_generic_lambdas_123 {
573void test() {
574  auto L = [](auto a) -> int {
575    auto M = [](auto b, decltype(a) b2) -> int {
576      return 1;
577    };
578    M(a, a);
579  };
580  L(3);
581}
582template<class T> void foo(T) {
583 auto L = [](auto a) { return a; };
584}
585template void foo(int);
586} // end ns nested_generic_lambdas_123
587
588
589} // end ns nested_non_capturing_lambda_tests
590