blob: 1228c74b0709beae4717225318f5f7579e9bbfeb [file] [log] [blame]
Richard Smithba71c082013-05-16 06:20:58 +00001// RUN: %clang_cc1 -std=c++1y %s -verify
2
Richard Smithbb13c9a2013-09-28 04:02:39 +00003const char *has_no_member = [x("hello")] {}.x; // expected-error {{no member named 'x'}}
Richard Smithba71c082013-05-16 06:20:58 +00004
Richard Smithbb13c9a2013-09-28 04:02:39 +00005double f;
6auto with_float = [f(1.0f)] {
7 using T = decltype(f);
8 using T = float;
9};
10auto with_float_2 = [&f(f)] { // ok, refers to outer f
11 using T = decltype(f);
12 using T = double&;
13};
Richard Smithba71c082013-05-16 06:20:58 +000014
Richard Smithbb13c9a2013-09-28 04:02:39 +000015// Within the lambda-expression's compound-statement,
16// the identifier in the init-capture hides any declaration
Richard Smithba71c082013-05-16 06:20:58 +000017// of the same name in scopes enclosing the lambda-expression.
18void hiding() {
19 char c;
20 (void) [c("foo")] {
21 static_assert(sizeof(c) == sizeof(const char*), "");
22 };
Richard Smithbb13c9a2013-09-28 04:02:39 +000023 (void) [c("bar")] () -> decltype(c) { // outer c, not init-capture
Richard Smithba71c082013-05-16 06:20:58 +000024 return "baz"; // expected-error {{cannot initialize}}
25 };
26}
27
28struct ExplicitCopy {
29 ExplicitCopy(); // expected-note 2{{not viable}}
30 explicit ExplicitCopy(const ExplicitCopy&);
31};
32auto init_kind_1 = [ec(ExplicitCopy())] {};
33auto init_kind_2 = [ec = ExplicitCopy()] {}; // expected-error {{no matching constructor}}
34
35template<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}
39template void init_kind_template<int>();
40template void init_kind_template<ExplicitCopy>(); // expected-note {{instantiation of}}
41
42void void_fn();
43int overload_fn();
44int overload_fn(int);
45
46auto bad_init_1 = [a()] {}; // expected-error {{expected expression}}
47auto bad_init_2 = [a(1, 2)] {}; // expected-error {{initializer for lambda capture 'a' contains multiple expressions}}
48auto bad_init_3 = [&a(void_fn())] {}; // expected-error {{cannot form a reference to 'void'}}
Richard Smithbb13c9a2013-09-28 04:02:39 +000049auto bad_init_4 = [a(void_fn())] {}; // expected-error {{has incomplete type 'void'}}
Richard Smithba71c082013-05-16 06:20:58 +000050auto bad_init_5 = [a(overload_fn)] {}; // expected-error {{cannot deduce type for lambda capture 'a' from initializer of type '<overloaded function}}
Richard Smith215f4232015-02-11 02:41:33 +000051auto bad_init_6 = [a{overload_fn}] {}; // expected-error {{cannot deduce type for lambda capture 'a' from initializer list}} expected-warning {{will change meaning in a future version of Clang}}
Richard Smithba71c082013-05-16 06:20:58 +000052
Richard Smithbb13c9a2013-09-28 04:02:39 +000053template<typename...T> void pack_1(T...t) { (void)[a(t...)] {}; } // expected-error {{initializer missing for lambda capture 'a'}}
Richard Smithba71c082013-05-16 06:20:58 +000054template void pack_1<>(); // expected-note {{instantiation of}}
55
Richard Smithbb13c9a2013-09-28 04:02:39 +000056// FIXME: Might need lifetime extension for the temporary here.
57// See DR1695.
58auto a = [a(4), b = 5, &c = static_cast<const int&&>(0)] {
Richard Smithba71c082013-05-16 06:20:58 +000059 static_assert(sizeof(a) == sizeof(int), "");
60 static_assert(sizeof(b) == sizeof(int), "");
61 using T = decltype(c);
62 using T = const int &;
63};
Richard Smith215f4232015-02-11 02:41:33 +000064auto b = [a{0}] {}; // expected-error {{include <initializer_list>}} expected-warning {{will change meaning in a future version of Clang}}
Richard Smithba71c082013-05-16 06:20:58 +000065
66struct S { S(); S(S&&); };
67template<typename T> struct remove_reference { typedef T type; };
68template<typename T> struct remove_reference<T&> { typedef T type; };
69template<typename T> decltype(auto) move(T &&t) { return static_cast<typename remove_reference<T>::type&&>(t); }
70auto s = [s(move(S()))] {};
Richard Smithbb13c9a2013-09-28 04:02:39 +000071
72template<typename T> T instantiate_test(T t) {
73 [x(&t)]() { *x = 1; } (); // expected-error {{assigning to 'const char *'}}
74 return t;
75}
76int instantiate_test_1 = instantiate_test(0);
77const char *instantiate_test_2 = instantiate_test("foo"); // expected-note {{here}}