cxx1y-generic-lambdas.cpp revision 9bd1c1332f7b2a82ed7b328b216a35a299a5945a
1// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -emit-llvm-only %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  int* (*fp)(int*) = [](auto *a) -> auto* { return a; };
58  fp(0);
59}
60}
61
62namespace more_converion_to_ptr_to_function_tests {
63
64
65int test() {
66  {
67    int& (*fpi)(int*) = [](auto* a) -> auto& { return *a; }; // OK
68    int (*fp2)(int) = [](auto b) -> int {  return b; };
69    int (*fp3)(char) = [](auto c) -> int { return c; };
70    char (*fp4)(int) = [](auto d) { return d; }; //expected-error{{no viable conversion}}\
71                                                 //expected-note{{candidate template ignored}}
72    char (*fp5)(char) = [](auto e) -> int { return e; }; //expected-error{{no viable conversion}}\
73                                                 //expected-note{{candidate template ignored}}
74
75    fp2(3);
76    fp3('\n');
77    fp3('a');
78    return 0;
79  }
80} // end test()
81
82template<class ... Ts> void vfun(Ts ... ) { }
83
84int variadic_test() {
85
86 int (*fp)(int, char, double) = [](auto ... a) -> int { vfun(a...); return 4; };
87 fp(3, '4', 3.14);
88
89 int (*fp2)(int, char, double) = [](auto ... a) { vfun(a...); return 4; };
90 fp(3, '4', 3.14);
91 return 2;
92}
93
94} // end ns
95
96namespace conversion_operator {
97void test() {
98    auto L = [](auto a) -> int { return a; };
99    int (*fp)(int) = L;
100    int (&fp2)(int) = [](auto a) { return a; };  // expected-error{{non-const lvalue}}
101    int (&&fp3)(int) = [](auto a) { return a; };  // expected-error{{no viable conversion}}\
102                                                  //expected-note{{candidate}}
103  }
104}
105}
106
107namespace return_type_deduction_ok {
108 auto l = [](auto a) ->auto { return a; }(2);
109 auto l2 = [](auto a) ->decltype(auto) { return a; }(2);
110 auto l3 = [](auto a) { return a; }(2);
111
112}
113
114namespace generic_lambda_as_default_argument_ok {
115  void test(int i = [](auto a)->int { return a; }(3)) {
116  }
117}
118
119namespace nested_non_capturing_lambda_tests {
120template<class ... Ts> void print(Ts ...) { }
121int test() {
122{
123  auto L = [](auto a) {
124    return [](auto b) {
125      return b;
126    };
127  };
128  auto M = L(3);
129  M(4.15);
130 }
131{
132  int i = 10; //expected-note{{declared here}}
133  auto L = [](auto a) {
134    return [](auto b) { //expected-note{{begins here}}
135      i = b;  //expected-error{{cannot be implicitly captured}}
136      return b;
137    };
138  };
139  auto M = L(3);
140  M(4.15); //expected-note{{instantiation}}
141 }
142 {
143  auto L = [](auto a) {
144    print("a = ", a, "\n");
145    return [](auto b) ->decltype(a) {
146      print("b = ", b, "\n");
147      return b;
148    };
149  };
150  auto M = L(3);
151  M(4.15);
152 }
153
154{
155  auto L = [](auto a) ->decltype(a) {
156    print("a = ", a, "\n");
157    return [](auto b) ->decltype(a) { //expected-error{{no viable conversion}}\
158                                      //expected-note{{candidate template ignored}}
159      print("b = ", b, "\n");
160      return b;
161    };
162  };
163  auto M = L(3); //expected-note{{in instantiation of}}
164 }
165{
166  auto L = [](auto a) {
167    print("a = ", a, "\n");
168    return [](auto ... b) ->decltype(a) {
169      print("b = ", b ..., "\n");
170      return 4;
171    };
172  };
173  auto M = L(3);
174  M(4.15, 3, "fv");
175}
176
177{
178  auto L = [](auto a) {
179    print("a = ", a, "\n");
180    return [](auto ... b) ->decltype(a) {
181      print("b = ", b ..., "\n");
182      return 4;
183    };
184  };
185  auto M = L(3);
186  int (*fp)(double, int, const char*) = M;
187  fp(4.15, 3, "fv");
188}
189
190{
191  auto L = [](auto a) {
192    print("a = ", a, "\n");
193    return [](char b) {
194      return [](auto ... c) ->decltype(b) {
195        print("c = ", c ..., "\n");
196        return 42;
197      };
198    };
199  };
200  L(4);
201  auto M = L(3);
202  M('a');
203  auto N = M('x');
204  N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
205  char (*np)(const char*, int, const char*, double, const char*, int) = N;
206  np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
207}
208
209
210{
211  auto L = [](auto a) {
212    print("a = ", a, "\n");
213    return [](decltype(a) b) {
214      return [](auto ... c) ->decltype(b) {
215        print("c = ", c ..., "\n");
216        return 42;
217      };
218    };
219  };
220  L('4');
221  auto M = L('3');
222  M('a');
223  auto N = M('x');
224  N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
225  char (*np)(const char*, int, const char*, double, const char*, int) = N;
226  np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
227}
228
229
230{
231 struct X {
232  static void foo(double d) { }
233  void test() {
234    auto L = [](auto a) {
235      print("a = ", a, "\n");
236      foo(a);
237      return [](decltype(a) b) {
238        foo(b);
239        foo(sizeof(a) + sizeof(b));
240        return [](auto ... c) ->decltype(b) {
241          print("c = ", c ..., "\n");
242          foo(decltype(b){});
243          foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
244          return 42;
245        };
246      };
247    };
248    L('4');
249    auto M = L('3');
250    M('a');
251    auto N = M('x');
252    N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
253    char (*np)(const char*, int, const char*, double, const char*, int) = N;
254    np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
255  }
256};
257X x;
258x.test();
259}
260// Make sure we can escape the function
261{
262 struct X {
263  static void foo(double d) { }
264  auto test() {
265    auto L = [](auto a) {
266      print("a = ", a, "\n");
267      foo(a);
268      return [](decltype(a) b) {
269        foo(b);
270        foo(sizeof(a) + sizeof(b));
271        return [](auto ... c) ->decltype(b) {
272          print("c = ", c ..., "\n");
273          foo(decltype(b){});
274          foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
275          return 42;
276        };
277      };
278    };
279    return L;
280  }
281};
282  X x;
283  auto L = x.test();
284  L('4');
285  auto M = L('3');
286  M('a');
287  auto N = M('x');
288  N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
289  char (*np)(const char*, int, const char*, double, const char*, int) = N;
290  np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
291}
292
293{
294 struct X {
295  static void foo(double d) { }
296  auto test() {
297    auto L = [](auto a) {
298      print("a = ", a, "\n");
299      foo(a);
300      return [](decltype(a) b) {
301        foo(b);
302        foo(sizeof(a) + sizeof(b));
303        return [](auto ... c) {
304          print("c = ", c ..., "\n");
305          foo(decltype(b){});
306          foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
307          return [](decltype(c) ... d) ->decltype(a) { //expected-note{{candidate}}
308            print("d = ", d ..., "\n");
309            foo(decltype(b){});
310            foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
311            return decltype(a){};
312          };
313        };
314      };
315    };
316    return L;
317  }
318};
319  X x;
320  auto L = x.test();
321  L('4');
322  auto M = L('3');
323  M('a');
324  auto N = M('x');
325  auto O = N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
326  char (*np)(const char*, int, const char*, double, const char*, int) = O;
327  np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
328  int (*np2)(const char*, int, const char*, double, const char*, int) = O; // expected-error{{no viable conversion}}
329
330}
331} // end test()
332
333namespace wrapped_within_templates {
334
335namespace explicit_return {
336template<class T> int fooT(T t) {
337  auto L = [](auto a) -> void {
338    auto M = [](char b) -> void {
339      auto N = [](auto c) -> void {
340        int x = 0;
341        x = sizeof(a);
342        x = sizeof(b);
343        x = sizeof(c);
344      };
345      N('a');
346      N(decltype(a){});
347    };
348  };
349  L(t);
350  L(3.14);
351  return 0;
352}
353
354int run = fooT('a') + fooT(3.14);
355
356} // end explicit_return
357
358namespace implicit_return_deduction {
359template<class T> auto fooT(T t) {
360  auto L = [](auto a)  {
361    auto M = [](char b)  {
362      auto N = [](auto c)  {
363        int x = 0;
364        x = sizeof(a);
365        x = sizeof(b);
366        x = sizeof(c);
367      };
368      N('a');
369      N(decltype(a){});
370    };
371  };
372  L(t);
373  L(3.14);
374  return 0;
375}
376
377int run = fooT('a') + fooT(3.14);
378
379template<class ... Ts> void print(Ts ... ts) { }
380
381template<class F, class ... Rest> using first = F;
382
383template<class ... Ts> auto fooV(Ts ... ts) {
384  auto L = [](auto ... a) {
385    auto M = [](decltype(a) ... b) {
386      auto N = [](auto c) {
387        int x = 0;
388        x = sizeof...(a);
389        x = sizeof...(b);
390        x = sizeof(c);
391      };
392      N('a');
393      N(N);
394      N(first<Ts...>{});
395    };
396    M(a...);
397    print("a = ", a..., "\n");
398  };
399  L(L, ts...);
400  print("ts = ", ts..., "\n");
401  return 0;
402}
403
404int run2 = fooV(3.14, " ", '4', 5) + fooV("BC", 3, 2.77, 'A', float{}, short{}, unsigned{});
405
406} //implicit_return_deduction
407
408
409} //wrapped_within_templates
410
411namespace at_ns_scope {
412  void foo(double d) { }
413  auto test() {
414    auto L = [](auto a) {
415      print("a = ", a, "\n");
416      foo(a);
417      return [](decltype(a) b) {
418        foo(b);
419        foo(sizeof(a) + sizeof(b));
420        return [](auto ... c) {
421          print("c = ", c ..., "\n");
422          foo(decltype(b){});
423          foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
424          return [](decltype(c) ... d) ->decltype(a) { //expected-note{{candidate}}
425            print("d = ", d ..., "\n");
426            foo(decltype(b){});
427            foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
428            return decltype(a){};
429          };
430        };
431      };
432    };
433    return L;
434  }
435auto L = test();
436auto L_test = L('4');
437auto M = L('3');
438auto M_test = M('a');
439auto N = M('x');
440auto O = N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
441char (*np)(const char*, int, const char*, double, const char*, int) = O;
442auto NP_result = np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
443int (*np2)(const char*, int, const char*, double, const char*, int) = O; // expected-error{{no viable conversion}}
444
445
446
447}
448
449namespace variadic_tests_1 {
450template<class ... Ts> void print(Ts ... ts) { }
451
452template<class F, class ... Rest> using FirstType = F;
453template<class F, class ... Rest> F& FirstArg(F& f, Rest...) { return f; }
454
455template<class ... Ts> int fooV(Ts ... ts) {
456  auto L = [](auto ... a) -> void {
457    auto M = [](decltype(a) ... b) -> void {
458      auto N = [](auto c) -> void {
459        int x = 0;
460        x = sizeof...(a);
461        x = sizeof...(b);
462        x = sizeof(c);
463      };
464      N('a');
465      N(N);
466      N(FirstType<Ts...>{});
467    };
468    M(a...);
469    print("a = ", a..., "\n");
470  };
471  L(L, ts...);
472  print("ts = ", ts..., "\n");
473  return 0;
474}
475
476int run2 = fooV(3.14, " ", '4', 5) + fooV("BC", 3, 2.77, 'A', float{}, short{}, unsigned{});
477
478namespace more_variadic_1 {
479
480template<class ... Ts> int fooV(Ts ... ts) {
481  auto L = [](auto ... a) {
482    auto M = [](decltype(a) ... b) -> void {
483      auto N = [](auto c) -> void {
484        int x = 0;
485        x = sizeof...(a);
486        x = sizeof...(b);
487        x = sizeof(c);
488      };
489      N('a');
490      N(N);
491      N(FirstType<Ts...>{});
492    };
493    M(a...);
494    return M;
495  };
496  auto M = L(L, ts...);
497  decltype(L(L, ts...)) (*fp)(decltype(L), decltype(ts) ...) = L;
498  void (*fp2)(decltype(L), decltype(ts) ...) = L(L, ts...);
499
500  {
501    auto L = [](auto ... a) {
502      auto M = [](decltype(a) ... b) {
503        auto N = [](auto c) -> void {
504          int x = 0;
505          x = sizeof...(a);
506          x = sizeof...(b);
507          x = sizeof(c);
508        };
509        N('a');
510        N(N);
511        N(FirstType<Ts...>{});
512        return N;
513      };
514      M(a...);
515      return M;
516    };
517    auto M = L(L, ts...);
518    decltype(L(L, ts...)) (*fp)(decltype(L), decltype(ts) ...) = L;
519    fp(L, ts...);
520    decltype(L(L, ts...)(L, ts...)) (*fp2)(decltype(L), decltype(ts) ...) = L(L, ts...);
521    fp2 = fp(L, ts...);
522    void (*fp3)(char) = fp2(L, ts...);
523    fp3('a');
524  }
525  return 0;
526}
527
528int run2 = fooV(3.14, " ", '4', 5) + fooV("BC", 3, 2.77, 'A', float{}, short{}, unsigned{});
529
530
531} //end ns more_variadic_1
532
533} // end ns variadic_tests_1
534
535namespace at_ns_scope_within_class_member {
536 struct X {
537  static void foo(double d) { }
538  auto test() {
539    auto L = [](auto a) {
540      print("a = ", a, "\n");
541      foo(a);
542      return [](decltype(a) b) {
543        foo(b);
544        foo(sizeof(a) + sizeof(b));
545        return [](auto ... c) {
546          print("c = ", c ..., "\n");
547          foo(decltype(b){});
548          foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
549          return [](decltype(c) ... d) ->decltype(a) { //expected-note{{candidate}}
550            print("d = ", d ..., "\n");
551            foo(decltype(b){});
552            foo(sizeof(decltype(a)*) + sizeof(decltype(b)*));
553            return decltype(a){};
554          };
555        };
556      };
557    };
558    return L;
559  }
560};
561X x;
562auto L = x.test();
563auto L_test = L('4');
564auto M = L('3');
565auto M_test = M('a');
566auto N = M('x');
567auto O = N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
568char (*np)(const char*, int, const char*, double, const char*, int) = O;
569auto NP_result = np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456);
570int (*np2)(const char*, int, const char*, double, const char*, int) = O; // expected-error{{no viable conversion}}
571
572} //end at_ns_scope_within_class_member
573
574
575namespace nested_generic_lambdas_123 {
576void test() {
577  auto L = [](auto a) -> int {
578    auto M = [](auto b, decltype(a) b2) -> int {
579      return 1;
580    };
581    M(a, a);
582  };
583  L(3);
584}
585template<class T> void foo(T) {
586 auto L = [](auto a) { return a; };
587}
588template void foo(int);
589} // end ns nested_generic_lambdas_123
590
591namespace nested_fptr_235 {
592int test()
593{
594  auto L = [](auto b) {
595    return [](auto a) ->decltype(a) { return a; };
596  };
597  int (*fp)(int) = L(8);
598  fp(5);
599  L(3);
600  char (*fc)(char) = L('a');
601  fc('b');
602  L('c');
603  double (*fd)(double) = L(3.14);
604  fd(3.14);
605  fd(6.26);
606  return 0;
607}
608int run = test();
609}
610
611
612namespace fptr_with_decltype_return_type {
613template<class F, class ... Ts> using FirstType = F;
614template<class F, class ... Rest> F& FirstArg(F& f, Rest& ... r) { return f; };
615template<class ... Ts> auto vfun(Ts&& ... ts) {
616  print(ts...);
617  return FirstArg(ts...);
618}
619int test()
620{
621 {
622   auto L = [](auto ... As) {
623    return [](auto b) ->decltype(b) {
624      vfun([](decltype(As) a) -> decltype(a) { return a; } ...)(FirstType<decltype(As)...>{});
625      return decltype(b){};
626    };
627   };
628   auto LL = L(1, 'a', 3.14, "abc");
629   LL("dim");
630 }
631  return 0;
632}
633int run = test();
634}
635
636} // end ns nested_non_capturing_lambda_tests
637
638namespace PR17476 {
639struct string {
640  string(const char *__s) { }
641  string &operator+=(const string &__str) { return *this; }
642};
643
644template <class T>
645void finalizeDefaultAtomValues() {
646  auto startEnd = [](const char * sym) -> void {
647    string start("__");
648    start += sym;
649  };
650  startEnd("preinit_array");
651}
652
653void f() { finalizeDefaultAtomValues<char>(); }
654
655}
656
657namespace PR17476_variant {
658struct string {
659  string(const char *__s) { }
660  string &operator+=(const string &__str) { return *this; }
661};
662
663template <class T>
664void finalizeDefaultAtomValues() {
665  auto startEnd = [](const T *sym) -> void {
666    string start("__");
667    start += sym;
668  };
669  startEnd("preinit_array");
670}
671
672void f() { finalizeDefaultAtomValues<char>(); }
673
674}