1 | // RUN: %clang_cc1 -std=c++1y %s -verify |
2 | |
3 | const char *has_no_member = [x("hello")] {}.x; // expected-error {{no member named 'x'}} |
4 | |
5 | double f; |
6 | auto with_float = [f(1.0f)] { |
7 | using T = decltype(f); |
8 | using T = float; |
9 | }; |
10 | auto with_float_2 = [&f(f)] { // ok, refers to outer f |
11 | using T = decltype(f); |
12 | using T = double&; |
13 | }; |
14 | |
15 | // Within the lambda-expression's compound-statement, |
16 | // the identifier in the init-capture hides any declaration |
17 | // of the same name in scopes enclosing the lambda-expression. |
18 | void hiding() { |
19 | char c; |
20 | (void) [c("foo")] { |
21 | static_assert(sizeof(c) == sizeof(const char*), ""); |
22 | }; |
23 | (void) [c("bar")] () -> decltype(c) { // outer c, not init-capture |
24 | return "baz"; // expected-error {{cannot initialize}} |
25 | }; |
26 | } |
27 | |
28 | struct ExplicitCopy { |
29 | ExplicitCopy(); // expected-note 2{{not viable}} |
30 | explicit ExplicitCopy(const ExplicitCopy&); |
31 | }; |
32 | auto init_kind_1 = [ec(ExplicitCopy())] {}; |
33 | auto init_kind_2 = [ec = ExplicitCopy()] {}; // expected-error {{no matching constructor}} |
34 | |
35 | template<typename T> void init_kind_template() { |
36 | auto init_kind_1 = [ec(T())] {}; |
37 | auto init_kind_2 = [ec = T()] {}; // expected-error {{no matching constructor}} |
38 | } |
39 | template void init_kind_template<int>(); |
40 | template void init_kind_template<ExplicitCopy>(); // expected-note {{instantiation of}} |
41 | |
42 | void void_fn(); |
43 | int overload_fn(); |
44 | int overload_fn(int); |
45 | |
46 | auto bad_init_1 = [a()] {}; // expected-error {{expected expression}} |
47 | auto bad_init_2 = [a(1, 2)] {}; // expected-error {{initializer for lambda capture 'a' contains multiple expressions}} |
48 | auto bad_init_3 = [&a(void_fn())] {}; // expected-error {{cannot form a reference to 'void'}} |
49 | auto bad_init_4 = [a(void_fn())] {}; // expected-error {{has incomplete type 'void'}} |
50 | auto bad_init_5 = [a(overload_fn)] {}; // expected-error {{cannot deduce type for lambda capture 'a' from initializer of type '<overloaded function}} |
51 | auto bad_init_6 = [a{overload_fn}] {}; // expected-error {{cannot deduce type for lambda capture 'a' from initializer list}} |
52 | auto bad_init_7 = [a{{1}}] {}; // expected-error {{cannot deduce type for lambda capture 'a' from nested initializer list}} |
53 | |
54 | template<typename...T> void pack_1(T...t) { (void)[a(t...)] {}; } // expected-error {{initializer missing for lambda capture 'a'}} |
55 | template void pack_1<>(); // expected-note {{instantiation of}} |
56 | |
57 | // FIXME: Might need lifetime extension for the temporary here. |
58 | // See DR1695. |
59 | auto a = [a(4), b = 5, &c = static_cast<const int&&>(0)] { |
60 | static_assert(sizeof(a) == sizeof(int), ""); |
61 | static_assert(sizeof(b) == sizeof(int), ""); |
62 | using T = decltype(c); |
63 | using T = const int &; |
64 | }; |
65 | auto b = [a{0}] {}; // OK, per N3922 |
66 | |
67 | struct S { S(); S(S&&); }; |
68 | template<typename T> struct remove_reference { typedef T type; }; |
69 | template<typename T> struct remove_reference<T&> { typedef T type; }; |
70 | template<typename T> decltype(auto) move(T &&t) { return static_cast<typename remove_reference<T>::type&&>(t); } |
71 | auto s = [s(move(S()))] {}; |
72 | |
73 | template<typename T> T instantiate_test(T t) { |
74 | [x(&t)]() { *x = 1; } (); // expected-error {{assigning to 'const char *'}} |
75 | return t; |
76 | } |
77 | int instantiate_test_1 = instantiate_test(0); |
78 | const char *instantiate_test_2 = instantiate_test("foo"); // expected-note {{here}} |
79 | |