p11-1y.cpp revision 0d8e9646bc000bab521ce52ed294209a92298cef
1// RUN: %clang_cc1 -std=c++1y %s -verify 2 3// For every init-capture a non-static data member named by the identifier of 4// the init-capture is declared in the closure type. 5const char *has_member_x = [x("hello")] {}.x; 6// This member is not a bit-field... 7auto capturing_lambda = [n(0)] {}; 8int decltype(capturing_lambda)::*mem_ptr = &decltype(capturing_lambda)::n; 9// ... and not mutable. 10const auto capturing_lambda_copy = capturing_lambda; 11int &n = capturing_lambda_copy.n; // expected-error {{drops qualifiers}} 12 13// The type of that member [...is that of a...] variable declaration of the form 14// "auto init-capture ;"... 15auto with_float = [f(1.0f)] {}; 16float &f = with_float.f; 17// ... except that the variable name is replaced by a unique identifier. 18auto with_float_2 = [&f(f)] {}; // ok, refers to outer f 19float &f2 = with_float_2.f; 20 21// Within the lambda-expression's lambda-declarator (FIXME) and 22// compound-statement, the identifier in the init-capture hides any declaration 23// of the same name in scopes enclosing the lambda-expression. 24void hiding() { 25 char c; 26 (void) [c("foo")] { 27 static_assert(sizeof(c) == sizeof(const char*), ""); 28 }; 29 (void) [c("bar")] () -> decltype(c) { 30 // FIXME: the 'c' in the return type should be the init-capture, not the 31 // outer c. 32 return "baz"; // expected-error {{cannot initialize}} 33 }; 34} 35 36struct ExplicitCopy { 37 ExplicitCopy(); // expected-note 2{{not viable}} 38 explicit ExplicitCopy(const ExplicitCopy&); 39}; 40auto init_kind_1 = [ec(ExplicitCopy())] {}; 41auto init_kind_2 = [ec = ExplicitCopy()] {}; // expected-error {{no matching constructor}} 42 43template<typename T> void init_kind_template() { 44 auto init_kind_1 = [ec(T())] {}; 45 auto init_kind_2 = [ec = T()] {}; // expected-error {{no matching constructor}} 46} 47template void init_kind_template<int>(); 48template void init_kind_template<ExplicitCopy>(); // expected-note {{instantiation of}} 49 50void void_fn(); 51int overload_fn(); 52int overload_fn(int); 53 54auto bad_init_1 = [a()] {}; // expected-error {{expected expression}} 55auto bad_init_2 = [a(1, 2)] {}; // expected-error {{initializer for lambda capture 'a' contains multiple expressions}} 56auto bad_init_3 = [&a(void_fn())] {}; // expected-error {{cannot form a reference to 'void'}} 57auto bad_init_4 = [a(void_fn())] {}; // expected-error {{field has incomplete type 'void'}} 58auto bad_init_5 = [a(overload_fn)] {}; // expected-error {{cannot deduce type for lambda capture 'a' from initializer of type '<overloaded function}} 59auto bad_init_6 = [a{overload_fn}] {}; // expected-error {{cannot deduce type for lambda capture 'a' from initializer list}} 60 61template<typename...T> void pack_1(T...t) { [a(t...)] {}; } // expected-error {{initializer missing for lambda capture 'a'}} 62template void pack_1<>(); // expected-note {{instantiation of}} 63 64auto multi_return(int a, int b) { 65 return [n(a + 2*b), m(a - 2*b)] {}; 66} 67auto use_multi_return() { 68 auto nm = multi_return(5, 9); 69 return nm.n + nm.m; 70} 71 72auto a = [a(4), b = 5, &c = static_cast<const int&&>(0)] { 73 static_assert(sizeof(a) == sizeof(int), ""); 74 static_assert(sizeof(b) == sizeof(int), ""); 75 using T = decltype(c); 76 using T = const int &; 77}; 78auto b = [a{0}] {}; // expected-error {{include <initializer_list>}} 79 80struct S { S(); S(S&&); }; 81template<typename T> struct remove_reference { typedef T type; }; 82template<typename T> struct remove_reference<T&> { typedef T type; }; 83template<typename T> decltype(auto) move(T &&t) { return static_cast<typename remove_reference<T>::type&&>(t); } 84auto s = [s(move(S()))] {}; 85