blob: b08d58abd2a9c3dedb590b76068427a95fdec868 [file] [log] [blame]
Faisal Valic00e4192013-11-07 05:17:06 +00001// 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
6constexpr int ODRUSE_SZ = sizeof(char);
7
8template<class T, int N>
9void f(T, const int (&)[N]) { }
10
11template<class T>
12void f(const T&, const int (&)[ODRUSE_SZ]) { }
13
14#define DEFINE_SELECTOR(x) \
15 int selector_ ## x[sizeof(x) == ODRUSE_SZ ? ODRUSE_SZ : ODRUSE_SZ + 5]
16
17#define F_CALL(x, a) f(x, selector_ ## a)
18
19// This is a risky assumption, because if an empty class gets captured by value
20// the lambda's size will still be '1'
21#define ASSERT_NO_CAPTURES(L) static_assert(sizeof(L) == 1, "size of closure with no captures must be 1")
22#define ASSERT_CLOSURE_SIZE_EXACT(L, N) static_assert(sizeof(L) == (N), "size of closure must be " #N)
23#define ASSERT_CLOSURE_SIZE(L, N) static_assert(sizeof(L) >= (N), "size of closure must be >=" #N)
24
25
26namespace sample {
27 struct X {
28 int i;
29 X(int i) : i(i) { }
30 };
31}
32
33namespace test_transformations_in_templates {
34template<class T> void foo(T t) {
35 auto L = [](auto a) { return a; };
36}
37template<class T> void foo2(T t) {
38 auto L = [](auto a) -> void {
39 auto M = [](char b) -> void {
40 auto N = [](auto c) -> void {
41 int selector[sizeof(c) == 1 ?
42 (sizeof(b) == 1 ? 1 : 2)
43 : 2
44 ]{};
45 };
46 N('a');
47 };
48 };
49 L(3.14);
50}
51
52void doit() {
53 foo(3);
54 foo('a');
55 foo2('A');
56}
57}
58
59namespace test_return_type_deduction {
60
61void doit() {
62
63 auto L = [](auto a, auto b) {
64 if ( a > b ) return a;
65 return b;
66 };
67 L(2, 4);
68 {
69 auto L2 = [](auto a, int i) {
70 return a + i;
71 };
72 L2(3.14, 2);
73 }
74 {
75 int a; //expected-note{{declared here}}
76 auto B = []() { return ^{ return a; }; }; //expected-error{{cannot be implicitly capture}}\
77 //expected-note{{begins here}}
78 //[](){ return ({int b = 5; return 'c'; 'x';}); };
79
80 //auto X = ^{ return a; };
81
82 //auto Y = []() -> auto { return 3; return 'c'; };
83
84 }
85}
86}
87
88
89namespace test_no_capture{
90void doit() {
91 const int x = 10; //expected-note{{declared here}}
92 {
93 // should not capture 'x' - variable undergoes lvalue-to-rvalue
94 auto L = [=](auto a) {
95 int y = x;
96 return a + y;
97 };
98 ASSERT_NO_CAPTURES(L);
99 }
100 {
101 // should not capture 'x' - even though certain instantiations require
102 auto L = [](auto a) { //expected-note{{begins here}}
103 DEFINE_SELECTOR(a);
104 F_CALL(x, a); //expected-error{{'x' cannot be implicitly captured}}
105 };
106 ASSERT_NO_CAPTURES(L);
107 L('s'); //expected-note{{in instantiation of}}
108 }
109 {
110 // Does not capture because no default capture in inner most lambda 'b'
111 auto L = [=](auto a) {
112 return [=](int p) {
113 return [](auto b) {
114 DEFINE_SELECTOR(a);
115 F_CALL(x, a);
116 return 0;
117 };
118 };
119 };
120 ASSERT_NO_CAPTURES(L);
121 }
122} // doit
123} // namespace
124
125namespace test_capture_of_potentially_evaluated_expression {
126void doit() {
127 const int x = 5;
128 {
129 auto L = [=](auto a) {
130 DEFINE_SELECTOR(a);
131 F_CALL(x, a);
132 };
133 static_assert(sizeof(L) == 4, "Must be captured");
134 }
135 {
136 int j = 0; //expected-note{{declared}}
137 auto L = [](auto a) { //expected-note{{begins here}}
138 return j + 1; //expected-error{{cannot be implicitly captured}}
139 };
140 }
141 {
142 const int x = 10;
143 auto L = [](auto a) {
144 //const int y = 20;
145 return [](int p) {
146 return [](auto b) {
147 DEFINE_SELECTOR(a);
148 F_CALL(x, a);
149 return 0;
150 };
151 };
152 };
153 auto M = L(3);
154 auto N = M(5);
155
156 }
157
158 { // if the nested capture does not implicitly or explicitly allow any captures
159 // nothing should capture - and instantiations will create errors if needed.
160 const int x = 0;
161 auto L = [=](auto a) { // <-- #A
162 const int y = 0;
163 return [](auto b) { // <-- #B
164 int c[sizeof(b)];
165 f(x, c);
166 f(y, c);
167 int i = x;
168 };
169 };
170 ASSERT_NO_CAPTURES(L);
171 auto M_int = L(2);
172 ASSERT_NO_CAPTURES(M_int);
173 }
174 { // Permutations of this example must be thoroughly tested!
175 const int x = 0;
176 sample::X cx{5};
177 auto L = [=](auto a) {
178 const int z = 3;
179 return [&,a](auto b) {
180 const int y = 5;
181 return [=](auto c) {
182 int d[sizeof(a) == sizeof(c) || sizeof(c) == sizeof(b) ? 2 : 1];
183 f(x, d);
184 f(y, d);
185 f(z, d);
186 decltype(a) A = a;
187 decltype(b) B = b;
188 const int &i = cx.i;
189 };
190 };
191 };
192 auto M = L(3)(3.5);
193 M(3.14);
194 }
195}
196namespace Test_no_capture_of_clearly_no_odr_use {
197auto foo() {
198 const int x = 10;
199 auto L = [=](auto a) {
200 return [=](auto b) {
201 return [=](auto c) {
202 int A = x;
203 return A;
204 };
205 };
206 };
207 auto M = L(1);
208 auto N = M(2.14);
209 ASSERT_NO_CAPTURES(L);
210 ASSERT_NO_CAPTURES(N);
211
212 return 0;
213}
214}
215
216namespace Test_capture_of_odr_use_var {
217auto foo() {
218 const int x = 10;
219 auto L = [=](auto a) {
220 return [=](auto b) {
221 return [=](auto c) {
222 int A = x;
223 const int &i = x;
224 decltype(a) A2 = a;
225 return A;
226 };
227 };
228 };
229 auto M_int = L(1);
230 auto N_int_int = M_int(2);
231 ASSERT_CLOSURE_SIZE_EXACT(L, sizeof(x));
232 // M_int captures both a & x
233 ASSERT_CLOSURE_SIZE_EXACT(M_int, sizeof(x) + sizeof(int));
234 // N_int_int captures both a & x
235 ASSERT_CLOSURE_SIZE_EXACT(N_int_int, sizeof(x) + sizeof(int));
236 auto M_double = L(3.14);
237 ASSERT_CLOSURE_SIZE(M_double, sizeof(x) + sizeof(double));
238
239 return 0;
240}
241auto run = foo();
242}
243
244}
245namespace more_nested_captures_1 {
246template<class T> struct Y {
247 static void f(int, double, ...) { }
248 template<class R>
249 static void f(const int&, R, ...) { }
250 template<class R>
251 void foo(R t) {
252 const int x = 10; //expected-note{{declared here}}
253 auto L = [](auto a) {
254 return [=](auto b) {
255 return [=](auto c) {
256 f(x, c, b, a); //expected-error{{reference to local variable 'x'}}
257 return 0;
258 };
259 };
260 };
261 auto M = L(t);
262 auto N = M('b');
263 N(3.14);
264 N(5); //expected-note{{in instantiation of}}
265 }
266};
267Y<int> yi;
268int run = (yi.foo(3.14), 0); //expected-note{{in instantiation of}}
269}
270
271
272namespace more_nested_captures_1_1 {
273template<class T> struct Y {
274 static void f(int, double, ...) { }
275 template<class R>
276 static void f(const int&, R, ...) { }
277 template<class R>
278 void foo(R t) {
279 const int x = 10; //expected-note{{declared here}}
280 auto L = [](auto a) {
281 return [=](char b) {
282 return [=](auto c) {
283 f(x, c, b, a); //expected-error{{reference to local variable 'x'}}
284 return 0;
285 };
286 };
287 };
288 auto M = L(t);
289 auto N = M('b');
290 N(3.14);
291 N(5); //expected-note{{in instantiation of}}
292 }
293};
294Y<int> yi;
295int run = (yi.foo(3.14), 0); //expected-note{{in instantiation of}}
296}
297namespace more_nested_captures_1_2 {
298template<class T> struct Y {
299 static void f(int, double, ...) { }
300 template<class R>
301 static void f(const int&, R, ...) { }
302 template<class R>
303 void foo(R t) {
304 const int x = 10;
305 auto L = [=](auto a) {
306 return [=](char b) {
307 return [=](auto c) {
308 f(x, c, b, a);
309 return 0;
310 };
311 };
312 };
313 auto M = L(t);
314 auto N = M('b');
315 N(3.14);
316 N(5);
317 }
318};
319Y<int> yi;
320int run = (yi.foo(3.14), 0);
321}
322
323namespace more_nested_captures_1_3 {
324template<class T> struct Y {
325 static void f(int, double, ...) { }
326 template<class R>
327 static void f(const int&, R, ...) { }
328 template<class R>
329 void foo(R t) {
330 const int x = 10; //expected-note{{declared here}}
331 auto L = [=](auto a) {
332 return [](auto b) {
333 const int y = 0;
334 return [=](auto c) {
335 f(x, c, b); //expected-error{{reference to local variable 'x'}}
336 f(y, b, c);
337 return 0;
338 };
339 };
340 };
341 auto M = L(t);
342 auto N = M('b');
343 N(3.14);
344 N(5); //expected-note{{in instantiation of}}
345 }
346};
347Y<int> yi;
348int run = (yi.foo(3.14), 0); //expected-note{{in instantiation of}}
349}
350
351
352namespace more_nested_captures_1_4 {
353template<class T> struct Y {
354 static void f(int, double, ...) { }
355 template<class R>
356 static void f(const int&, R, ...) { }
357 template<class R>
358 void foo(R t) {
359 const int x = 10; //expected-note{{declared here}}
360 auto L = [=](auto a) {
361 T t2{t};
362 return [](auto b) {
363 const int y = 0; //expected-note{{declared here}}
364 return [](auto c) { //expected-note 2{{lambda expression begins here}}
365 f(x, c); //expected-error{{variable 'x'}}
366 f(y, c); //expected-error{{variable 'y'}}
367 return 0;
368 };
369 };
370 };
371 auto M = L(t);
372 auto N_char = M('b');
373 N_char(3.14);
374 auto N_double = M(3.14);
375 N_double(3.14);
376 N_char(3); //expected-note{{in instantiation of}}
377 }
378};
379Y<int> yi;
380int run = (yi.foo('a'), 0); //expected-note{{in instantiation of}}
381}
382
383
384namespace more_nested_captures_2 {
385template<class T> struct Y {
386 static void f(int, double) { }
387 template<class R>
388 static void f(const int&, R) { }
389 template<class R>
390 void foo(R t) {
391 const int x = 10;
392 auto L = [=](auto a) {
393 return [=](auto b) {
394 return [=](auto c) {
395 f(x, c);
396 return 0;
397 };
398 };
399 };
400 auto M = L(t);
401 auto N = M('b');
402 N(3);
403 N(3.14);
404 }
405};
406Y<int> yi;
407int run = (yi.foo(3.14), 0);
408
409}
410
411namespace more_nested_captures_3 {
412template<class T> struct Y {
413 static void f(int, double) { }
414 template<class R>
415 static void f(const int&, R) { }
416 template<class R>
417 void foo(R t) {
418 const int x = 10; //expected-note{{declared here}}
419 auto L = [](auto a) {
420 return [=](auto b) {
421 return [=](auto c) {
422 f(x, c); //expected-error{{reference to local variable 'x'}}
423 return 0;
424 };
425 };
426 };
427 auto M = L(t);
428 auto N = M('b');
429 N(3); //expected-note{{in instantiation of}}
430 N(3.14);
431 }
432};
433Y<int> yi;
434int run = (yi.foo(3.14), 0); //expected-note{{in instantiation of}}
435
436}
437
438namespace more_nested_captures_4 {
439template<class T> struct Y {
440 static void f(int, double) { }
441 template<class R>
442 static void f(const int&, R) { }
443 template<class R>
444 void foo(R t) {
445 const int x = 10; //expected-note{{'x' declared here}}
446 auto L = [](auto a) {
447 return [=](char b) {
448 return [=](auto c) {
449 f(x, c); //expected-error{{reference to local variable 'x'}}
450 return 0;
451 };
452 };
453 };
454 auto M = L(t);
455 auto N = M('b');
456 N(3); //expected-note{{in instantiation of}}
457 N(3.14);
458 }
459};
460Y<int> yi;
461int run = (yi.foo(3.14), 0); //expected-note{{in instantiation of}}
462
463}
464
465namespace more_nested_captures_5 {
466template<class T> struct Y {
467 static void f(int, double) { }
468 template<class R>
469 static void f(const int&, R) { }
470 template<class R>
471 void foo(R t) {
472 const int x = 10;
473 auto L = [=](auto a) {
474 return [=](char b) {
475 return [=](auto c) {
476 f(x, c);
477 return 0;
478 };
479 };
480 };
481 auto M = L(t);
482 auto N = M('b');
483 N(3);
484 N(3.14);
485 }
486};
487Y<int> yi;
488int run = (yi.foo(3.14), 0);
489
490}
491
492namespace lambdas_in_NSDMIs {
493template<class T>
494 struct L {
495 T t{};
496 T t2 = ([](auto a) { return [](auto b) { return b; };})(t)(t);
497 T t3 = ([](auto a) { return a; })(t);
498 };
499 L<int> l;
500 int run = l.t2;
501}
502namespace test_nested_decltypes_in_trailing_return_types {
503int foo() {
504 auto L = [](auto a) {
505 return [](auto b, decltype(a) b2) -> decltype(a) {
506 return decltype(a){};
507 };
508 };
509 auto M = L(3.14);
510 M('a', 6.26);
511 return 0;
512}
513}
514
515namespace more_this_capture_1 {
516struct X {
517 void f(int) { }
518 static void f(double) { }
519 void foo() {
520 {
521 auto L = [=](auto a) {
522 f(a);
523 };
524 L(3);
525 L(3.13);
526 }
527 {
528 auto L = [](auto a) {
529 f(a); //expected-error{{this}}
530 };
531 L(3.13);
532 L(2); //expected-note{{in instantiation}}
533 }
534 }
535
536 int g() {
537 auto L = [=](auto a) {
538 return [](int i) {
539 return [=](auto b) {
540 f(b);
541 int x = i;
542 };
543 };
544 };
545 auto M = L(0.0);
546 auto N = M(3);
547 N(5.32); // OK
548 return 0;
549 }
550};
551int run = X{}.g();
552}
553namespace more_this_capture_1_1 {
554struct X {
555 void f(int) { }
556 static void f(double) { }
557
558 int g() {
559 auto L = [=](auto a) {
560 return [](int i) {
561 return [=](auto b) {
562 f(decltype(a){}); //expected-error{{this}}
563 int x = i;
564 };
565 };
566 };
567 auto M = L(0.0);
568 auto N = M(3);
569 N(5.32); // OK
570 L(3); // expected-note{{instantiation}}
571 return 0;
572 }
573};
574int run = X{}.g();
575}
576
577namespace more_this_capture_1_1_1 {
578struct X {
579 void f(int) { }
580 static void f(double) { }
581
582 int g() {
583 auto L = [=](auto a) {
584 return [](auto b) {
585 return [=](int i) {
586 f(b);
587 f(decltype(a){}); //expected-error{{this}}
588 };
589 };
590 };
591 auto M = L(0.0); // OK
592 auto N = M(3.3); //OK
593 auto M_int = L(0); //expected-note{{instantiation}}
594 return 0;
595 }
596};
597int run = X{}.g();
598}
599
600
601namespace more_this_capture_1_1_1_1 {
602struct X {
603 void f(int) { }
604 static void f(double) { }
605
606 int g() {
607 auto L = [=](auto a) {
608 return [](auto b) {
609 return [=](int i) {
610 f(b); //expected-error{{this}}
611 f(decltype(a){});
612 };
613 };
614 };
615 auto M_double = L(0.0); // OK
616 auto N = M_double(3); //expected-note{{instantiation}}
617
618 return 0;
619 }
620};
621int run = X{}.g();
622}
623
624namespace more_this_capture_2 {
625struct X {
626 void f(int) { }
627 static void f(double) { }
628
629 int g() {
630 auto L = [=](auto a) {
631 return [](int i) {
632 return [=](auto b) {
633 f(b); //expected-error{{'this' cannot}}
634 int x = i;
635 };
636 };
637 };
638 auto M = L(0.0);
639 auto N = M(3);
640 N(5); // NOT OK expected-note{{in instantiation of}}
641 return 0;
642 }
643};
644int run = X{}.g();
645}
646namespace diagnose_errors_early_in_generic_lambdas {
647
648int foo()
649{
650
651 { // This variable is used and must be caught early, do not need instantiation
652 const int x = 0; //expected-note{{declared}}
653 auto L = [](auto a) { //expected-note{{begins}}
654 const int &r = x; //expected-error{{variable}}
655 };
656 }
657 { // This variable is not used
658 const int x = 0;
659 auto L = [](auto a) {
660 int i = x;
661 };
662 }
663 {
664
665 const int x = 0; //expected-note{{declared}}
666 auto L = [=](auto a) { // <-- #A
667 const int y = 0;
668 return [](auto b) { //expected-note{{begins}}
669 int c[sizeof(b)];
670 f(x, c);
671 f(y, c);
672 int i = x;
673 // This use will always be an error regardless of instantatiation
674 // so diagnose this early.
675 const int &r = x; //expected-error{{variable}}
676 };
677 };
678
679 }
680 return 0;
681}
682
683int run = foo();
684}
685
686namespace generic_nongenerics_interleaved_1 {
687int foo() {
688 {
689 auto L = [](int a) {
690 int y = 10;
691 return [=](auto b) {
692 return a + y;
693 };
694 };
695 auto M = L(3);
696 M(5);
697 }
698 {
699 int x;
700 auto L = [](int a) {
701 int y = 10;
702 return [=](auto b) {
703 return a + y;
704 };
705 };
706 auto M = L(3);
707 M(5);
708 }
709 {
710 // FIXME: why are there 2 error messages here?
711 int x;
712 auto L = [](auto a) { //expected-note {{declared here}}
713 int y = 10; //expected-note {{declared here}}
714 return [](int b) { //expected-note 2{{expression begins here}}
715 return [=] (auto c) {
716 return a + y; //expected-error 2{{cannot be implicitly captured}}
717 };
718 };
719 };
720 }
721 {
722 int x;
723 auto L = [](auto a) {
724 int y = 10;
725 return [=](int b) {
726 return [=] (auto c) {
727 return a + y;
728 };
729 };
730 };
731 }
732 return 1;
733}
734
735int run = foo();
736}
737namespace dont_capture_refs_if_initialized_with_constant_expressions {
738
739auto foo(int i) {
740 // This is surprisingly not odr-used within the lambda!
741 static int j;
742 j = i;
743 int &ref_j = j;
744 return [](auto a) { return ref_j; }; // ok
745}
746
747template<class T>
748auto foo2(T t) {
749 // This is surprisingly not odr-used within the lambda!
750 static T j;
751 j = t;
752 T &ref_j = j;
753 return [](auto a) { return ref_j; }; // ok
754}
755
756int do_test() {
757 auto L = foo(3);
758 auto L_int = L(3);
759 auto L_char = L('a');
760 auto L1 = foo2(3.14);
761 auto L1_int = L1(3);
762 auto L1_char = L1('a');
763 return 0;
764}
765
766} // dont_capture_refs_if_initialized_with_constant_expressions
767
768namespace test_conversion_to_fptr {
769
770template<class T> struct X {
771
772 T (*fp)(T) = [](auto a) { return a; };
773
774};
775
776X<int> xi;
777
778template<class T>
779void fooT(T t, T (*fp)(T) = [](auto a) { return a; }) {
780 fp(t);
781}
782
783int test() {
784{
785 auto L = [](auto a) { return a; };
786 int (*fp)(int) = L;
787 fp(5);
788 L(3);
789 char (*fc)(char) = L;
790 fc('b');
791 L('c');
792 double (*fd)(double) = L;
793 fd(3.14);
794 fd(6.26);
795 L(4.25);
796}
797{
798 auto L = [](auto a) ->int { return a; }; //expected-note 2{{candidate template ignored}}
799 int (*fp)(int) = L;
800 char (*fc)(char) = L; //expected-error{{no viable conversion}}
801 double (*fd)(double) = L; //expected-error{{no viable conversion}}
802}
803{
804 int x = 5;
805 auto L = [=](auto b, char c = 'x') {
806 int i = x;
807 return [](auto a) ->decltype(a) { return a; };
808 };
809 int (*fp)(int) = L(8);
810 fp(5);
811 L(3);
812 char (*fc)(char) = L('a');
813 fc('b');
814 L('c');
815 double (*fd)(double) = L(3.14);
816 fd(3.14);
817 fd(6.26);
818
819}
820{
821 auto L = [=](auto b) {
822 return [](auto a) ->decltype(b)* { return (decltype(b)*)0; };
823 };
824 int* (*fp)(int) = L(8);
825 fp(5);
826 L(3);
827 char* (*fc)(char) = L('a');
828 fc('b');
829 L('c');
830 double* (*fd)(double) = L(3.14);
831 fd(3.14);
832 fd(6.26);
833}
834{
835 auto L = [=](auto b) {
836 return [](auto a) ->decltype(b)* { return (decltype(b)*)0; }; //expected-note{{candidate template ignored}}
837 };
838 char* (*fp)(int) = L('8');
839 fp(5);
840 char* (*fc)(char) = L('a');
841 fc('b');
842 double* (*fi)(int) = L(3.14);
843 fi(5);
844 int* (*fi2)(int) = L(3.14); //expected-error{{no viable conversion}}
845}
846
847{
848 auto L = [=](auto b) {
849 return [](auto a) {
850 return [=](auto c) {
851 return [](auto d) ->decltype(a + b + c + d) { return d; };
852 };
853 };
854 };
855 int (*fp)(int) = L('8')(3)(short{});
856 double (*fs)(char) = L(3.14)(short{})('4');
857}
858
859 fooT(3);
860 fooT('a');
861 fooT(3.14);
862 fooT("abcdefg");
863 return 0;
864}
865int run2 = test();
866
867}
868
869
870namespace this_capture {
871void f(char, int) { }
872template<class T>
873void f(T, const int&) { }
874
875struct X {
876 int x = 0;
877 void foo() {
878 auto L = [=](auto a) {
879 return [=](auto b) {
880 //f(a, x++);
881 x++;
882 };
883 };
884 L('a')(5);
885 L('b')(4);
886 L(3.14)('3');
887
888 }
889
890};
891
892int run = (X{}.foo(), 0);
893
894namespace this_capture_unresolvable {
895struct X {
896 void f(int) { }
897 static void f(double) { }
898
899 int g() {
900 auto lam = [=](auto a) { f(a); }; // captures 'this'
901 lam(0); // ok.
902 lam(0.0); // ok.
903 return 0;
904 }
905 int g2() {
906 auto lam = [](auto a) { f(a); }; // expected-error{{'this'}}
907 lam(0); // expected-note{{in instantiation of}}
908 lam(0.0); // ok.
909 return 0;
910 }
911 double (*fd)(double) = [](auto a) { f(a); return a; };
912
913};
914
915int run = X{}.g();
916
917}
918
919namespace check_nsdmi_and_this_capture_of_member_functions {
920
921struct FunctorDouble {
922 template<class T> FunctorDouble(T t) { t(2.14); };
923};
924struct FunctorInt {
925 template<class T> FunctorInt(T t) { t(2); }; //expected-note{{in instantiation of}}
926};
927
928template<class T> struct YUnresolvable {
929 void f(int) { }
930 static void f(double) { }
931
932 T t = [](auto a) { f(a); return a; };
933 T t2 = [=](auto b) { f(b); return b; };
934};
935
936template<class T> struct YUnresolvable2 {
937 void f(int) { }
938 static void f(double) { }
939
940 T t = [](auto a) { f(a); return a; }; //expected-error{{'this'}} \
941 //expected-note{{in instantiation of}}
942 T t2 = [=](auto b) { f(b); return b; };
943};
944
945
946YUnresolvable<FunctorDouble> yud;
947// This will cause an error since it call's with an int and calls a member function.
948YUnresolvable2<FunctorInt> yui;
949
950
951template<class T> struct YOnlyStatic {
952 static void f(double) { }
953
954 T t = [](auto a) { f(a); return a; };
955};
956YOnlyStatic<FunctorDouble> yos;
957template<class T> struct YOnlyNonStatic {
958 void f(int) { }
959
960 T t = [](auto a) { f(a); return a; }; //expected-error{{'this'}}
961};
962
963
964}
965
966
967namespace check_nsdmi_and_this_capture_of_data_members {
968
969struct FunctorDouble {
970 template<class T> FunctorDouble(T t) { t(2.14); };
971};
972struct FunctorInt {
973 template<class T> FunctorInt(T t) { t(2); };
974};
975
976template<class T> struct YThisCapture {
977 const int x = 10;
978 static double d;
979 T t = [](auto a) { return x; }; //expected-error{{'this'}}
980 T t2 = [](auto b) { return d; };
981 T t3 = [this](auto a) {
982 return [=](auto b) {
983 return x;
984 };
985 };
986 T t4 = [=](auto a) {
987 return [=](auto b) {
988 return x;
989 };
990 };
991 T t5 = [](auto a) {
992 return [=](auto b) {
993 return x; //expected-error{{'this'}}
994 };
995 };
996};
997
998template<class T> double YThisCapture<T>::d = 3.14;
999
1000
1001}
1002
1003
1004#ifdef DELAYED_TEMPLATE_PARSING
1005template<class T> void foo_no_error(T t) {
1006 auto L = []()
1007 { return t; };
1008}
1009template<class T> void foo(T t) { //expected-note 2{{declared here}}
1010 auto L = []() //expected-note 2{{begins here}}
1011 { return t; }; //expected-error 2{{cannot be implicitly captured}}
1012}
1013template void foo(int); //expected-note{{in instantiation of}}
1014
1015#else
1016
1017template<class T> void foo(T t) { //expected-note{{declared here}}
1018 auto L = []() //expected-note{{begins here}}
1019 { return t; }; //expected-error{{cannot be implicitly captured}}
1020}
1021
1022#endif
1023}
1024
1025namespace no_this_capture_for_static {
1026
1027struct X {
1028 static void f(double) { }
1029
1030 int g() {
1031 auto lam = [=](auto a) { f(a); };
1032 lam(0); // ok.
1033 ASSERT_NO_CAPTURES(lam);
1034 return 0;
1035 }
1036};
1037
1038int run = X{}.g();
1039}
1040
1041namespace this_capture_for_non_static {
1042
1043struct X {
1044 void f(double) { }
1045
1046 int g() {
1047 auto L = [=](auto a) { f(a); };
1048 L(0);
1049 auto L2 = [](auto a) { f(a); }; //expected-error {{cannot be implicitly captured}}
1050 return 0;
1051 }
1052};
1053
1054int run = X{}.g();
1055}
1056
1057namespace this_captures_with_num_args_disambiguation {
1058
1059struct X {
1060 void f(int) { }
1061 static void f(double, int i) { }
1062 int g() {
1063 auto lam = [](auto a) { f(a, a); };
1064 lam(0);
1065 return 0;
1066 }
1067};
1068
1069int run = X{}.g();
1070}
1071namespace enclosing_function_is_template_this_capture {
1072// Only error if the instantiation tries to use the member function.
1073struct X {
1074 void f(int) { }
1075 static void f(double) { }
1076 template<class T>
1077 int g(T t) {
1078 auto L = [](auto a) { f(a); }; //expected-error{{'this'}}
1079 L(t); // expected-note{{in instantiation of}}
1080 return 0;
1081 }
1082};
1083
1084int run = X{}.g(0.0); // OK.
1085int run2 = X{}.g(0); // expected-note{{in instantiation of}}
1086
1087
1088}
1089
1090namespace enclosing_function_is_template_this_capture_2 {
1091// This should error, even if not instantiated, since
1092// this would need to be captured.
1093struct X {
1094 void f(int) { }
1095 template<class T>
1096 int g(T t) {
1097 auto L = [](auto a) { f(a); }; //expected-error{{'this'}}
1098 L(t);
1099 return 0;
1100 }
1101};
1102
1103}
1104
1105
1106namespace enclosing_function_is_template_this_capture_3 {
1107// This should not error, this does not need to be captured.
1108struct X {
1109 static void f(int) { }
1110 template<class T>
1111 int g(T t) {
1112 auto L = [](auto a) { f(a); };
1113 L(t);
1114 return 0;
1115 }
1116};
1117
1118int run = X{}.g(0.0); // OK.
1119int run2 = X{}.g(0); // OK.
1120
1121}
1122
1123namespace nested_this_capture_1 {
1124struct X {
1125 void f(int) { }
1126 static void f(double) { }
1127
1128 int g() {
1129 auto L = [=](auto a) {
1130 return [this]() {
1131 return [=](auto b) {
1132 f(b);
1133 };
1134 };
1135 };
1136 auto M = L(0);
1137 auto N = M();
1138 N(5);
1139 return 0;
1140 }
1141};
1142
1143int run = X{}.g();
1144
1145}
1146
1147
1148namespace nested_this_capture_2 {
1149struct X {
1150 void f(int) { }
1151 static void f(double) { }
1152
1153 int g() {
1154 auto L = [=](auto a) {
1155 return [&]() {
1156 return [=](auto b) {
1157 f(b);
1158 };
1159 };
1160 };
1161 auto M = L(0);
1162 auto N = M();
1163 N(5);
1164 N(3.14);
1165 return 0;
1166 }
1167};
1168
1169int run = X{}.g();
1170
1171}
1172
1173namespace nested_this_capture_3_1 {
1174struct X {
1175 template<class T>
1176 void f(int, T t) { }
1177 template<class T>
1178 static void f(double, T t) { }
1179
1180 int g() {
1181 auto L = [=](auto a) {
1182 return [&](auto c) {
1183 return [=](auto b) {
1184 f(b, c);
1185 };
1186 };
1187 };
1188 auto M = L(0);
1189 auto N = M('a');
1190 N(5);
1191 N(3.14);
1192 return 0;
1193 }
1194};
1195
1196int run = X{}.g();
1197
1198}
1199
1200
1201namespace nested_this_capture_3_2 {
1202struct X {
1203 void f(int) { }
1204 static void f(double) { }
1205
1206 int g() {
1207 auto L = [=](auto a) {
1208 return [](int i) {
1209 return [=](auto b) {
1210 f(b); //expected-error {{'this' cannot}}
1211 int x = i;
1212 };
1213 };
1214 };
1215 auto M = L(0.0);
1216 auto N = M(3);
1217 N(5); //expected-note {{in instantiation of}}
1218 N(3.14); // OK.
1219 return 0;
1220 }
1221};
1222
1223int run = X{}.g();
1224
1225}
1226
1227namespace nested_this_capture_4 {
1228struct X {
1229 void f(int) { }
1230 static void f(double) { }
1231
1232 int g() {
1233 auto L = [](auto a) {
1234 return [=](auto i) {
1235 return [=](auto b) {
1236 f(b); //expected-error {{'this' cannot}}
1237 int x = i;
1238 };
1239 };
1240 };
1241 auto M = L(0.0);
1242 auto N = M(3);
1243 N(5); //expected-note {{in instantiation of}}
1244 N(3.14); // OK.
1245 return 0;
1246 }
1247};
1248
1249int run = X{}.g();
1250
1251}
1252namespace capture_enclosing_function_parameters {
1253
1254
1255inline auto foo(int x) {
1256 int i = 10;
1257 auto lambda = [=](auto z) { return x + z; };
1258 return lambda;
1259}
1260
1261int foo2() {
1262 auto L = foo(3);
1263 L(4);
1264 L('a');
1265 L(3.14);
1266 return 0;
1267}
1268
1269inline auto foo3(int x) {
1270 int local = 1;
1271 auto L = [=](auto a) {
1272 int i = a[local];
1273 return [=](auto b) mutable {
1274 auto n = b;
1275 return [&, n](auto c) mutable {
1276 ++local;
1277 return ++x;
1278 };
1279 };
1280 };
1281 auto M = L("foo-abc");
1282 auto N = M("foo-def");
1283 auto O = N("foo-ghi");
1284
1285 return L;
1286}
1287
1288int main() {
1289 auto L3 = foo3(3);
1290 auto M3 = L3("L3-1");
1291 auto N3 = M3("M3-1");
1292 auto O3 = N3("N3-1");
1293 N3("N3-2");
1294 M3("M3-2");
1295 M3("M3-3");
1296 L3("L3-2");
1297}
1298} // end ns
1299
1300namespace capture_arrays {
1301
1302inline int sum_array(int n) {
1303 int array2[5] = { 1, 2, 3, 4, 5};
1304
1305 auto L = [=](auto N) -> int {
1306 int sum = 0;
1307 int array[5] = { 1, 2, 3, 4, 5 };
1308 sum += array2[sum];
1309 sum += array2[N];
1310 return 0;
1311 };
1312 L(2);
1313 return L(n);
1314}
1315}
1316
1317namespace capture_non_odr_used_variable_because_named_in_instantiation_dependent_expressions {
1318
1319// even though 'x' is not odr-used, it should be captured.
1320
1321int test() {
1322 const int x = 10;
1323 auto L = [=](auto a) {
1324 (void) +x + a;
1325 };
1326 ASSERT_CLOSURE_SIZE_EXACT(L, sizeof(x));
1327}
1328
1329} //end ns
1330#ifdef MS_EXTENSIONS
1331namespace explicit_spec {
1332template<class R> struct X {
1333 template<class T> int foo(T t) {
1334 auto L = [](auto a) { return a; };
1335 L(&t);
1336 return 0;
1337 }
1338
1339 template<> int foo<char>(char c) { //expected-warning{{explicit specialization}}
1340 const int x = 10;
1341 auto LC = [](auto a) { return a; };
1342 R r;
1343 LC(&r);
1344 auto L = [=](auto a) {
1345 return [=](auto b) {
1346 int d[sizeof(a)];
1347 f(x, d);
1348 };
1349 };
1350 auto M = L(1);
1351
1352 ASSERT_NO_CAPTURES(M);
1353 return 0;
1354 }
1355
1356};
1357
1358int run_char = X<int>{}.foo('a');
1359int run_int = X<double>{}.foo(4);
1360}
Faisal Valic00e4192013-11-07 05:17:06 +00001361#endif // MS_EXTENSIONS
1362
Stephen Hinesc568f1e2014-07-21 00:47:37 -07001363namespace nsdmi_capturing_this {
1364struct X {
1365 int m = 10;
1366 int n = [this](auto) { return m; }(20);
1367};
1368
1369template<class T>
1370struct XT {
1371 T m = 10;
1372 T n = [this](auto) { return m; }(20);
1373};
1374
1375XT<int> xt{};
1376
1377
1378}