diff options
Diffstat (limited to 'clang/test/CXX/expr/expr.prim/expr.prim.lambda')
3 files changed, 110 insertions, 0 deletions
diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p11-1y.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p11-1y.cpp new file mode 100644 index 00000000000..0eec331b28c --- /dev/null +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p11-1y.cpp @@ -0,0 +1,84 @@ +// RUN: %clang_cc1 -std=c++1y %s -verify + +// For every init-capture a non-static data member named by the identifier of +// the init-capture is declared in the closure type. +const char *has_member_x = [x("hello")] {}.x; +// This member is not a bit-field... +auto capturing_lambda = [n(0)] {}; +int decltype(capturing_lambda)::*mem_ptr = &decltype(capturing_lambda)::n; +// ... and not mutable. +const auto capturing_lambda_copy = capturing_lambda; +int &n = capturing_lambda_copy.n; // expected-error {{drops qualifiers}} + +// The type of that member [...is that of a...] variable declaration of the form +// "auto init-capture ;"... +auto with_float = [f(1.0f)] {}; +float &f = with_float.f; +// ... except that the variable name is replaced by a unique identifier. +auto with_float_2 = [&f(f)] {}; // ok, refers to outer f +float &f2 = with_float_2.f; + +// Within the lambda-expression's lambda-declarator (FIXME) and +// compound-statement, the identifier in the init-capture hides any declaration +// of the same name in scopes enclosing the lambda-expression. +void hiding() { + char c; + (void) [c("foo")] { + static_assert(sizeof(c) == sizeof(const char*), ""); + }; + (void) [c("bar")] () -> decltype(c) { + // FIXME: the 'c' in the return type should be the init-capture, not the + // outer c. + return "baz"; // expected-error {{cannot initialize}} + }; +} + +struct ExplicitCopy { + ExplicitCopy(); // expected-note 2{{not viable}} + explicit ExplicitCopy(const ExplicitCopy&); +}; +auto init_kind_1 = [ec(ExplicitCopy())] {}; +auto init_kind_2 = [ec = ExplicitCopy()] {}; // expected-error {{no matching constructor}} + +template<typename T> void init_kind_template() { + auto init_kind_1 = [ec(T())] {}; + auto init_kind_2 = [ec = T()] {}; // expected-error {{no matching constructor}} +} +template void init_kind_template<int>(); +template void init_kind_template<ExplicitCopy>(); // expected-note {{instantiation of}} + +void void_fn(); +int overload_fn(); +int overload_fn(int); + +auto bad_init_1 = [a()] {}; // expected-error {{expected expression}} +auto bad_init_2 = [a(1, 2)] {}; // expected-error {{initializer for lambda capture 'a' contains multiple expressions}} +auto bad_init_3 = [&a(void_fn())] {}; // expected-error {{cannot form a reference to 'void'}} +auto bad_init_4 = [a(void_fn())] {}; // expected-error {{field has incomplete type 'void'}} +auto bad_init_5 = [a(overload_fn)] {}; // expected-error {{cannot deduce type for lambda capture 'a' from initializer of type '<overloaded function}} +auto bad_init_6 = [a{overload_fn}] {}; // expected-error {{cannot deduce type for lambda capture 'a' from initializer list}} + +template<typename...T> void pack_1(T...t) { [a(t...)] {}; } // expected-error {{initializer missing for lambda capture 'a'}} +template void pack_1<>(); // expected-note {{instantiation of}} + +auto multi_return(int a, int b) { + return [n(a + 2*b), m(a - 2*b)] {}; +} +auto use_multi_return() { + auto nm = multi_return(5, 9); + return nm.n + nm.m; +} + +auto a = [a(4), b = 5, &c = static_cast<const int&&>(0)] { + static_assert(sizeof(a) == sizeof(int), ""); + static_assert(sizeof(b) == sizeof(int), ""); + using T = decltype(c); + using T = const int &; +}; +auto b = [a{0}] {}; // expected-error {{include <initializer_list>}} + +struct S { S(); S(S&&); }; +template<typename T> struct remove_reference { typedef T type; }; +template<typename T> struct remove_reference<T&> { typedef T type; }; +template<typename T> decltype(auto) move(T &&t) { return static_cast<typename remove_reference<T>::type&&>(t); } +auto s = [s(move(S()))] {}; diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp index 82fc04a48fb..174ae6d5b09 100644 --- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify +// RUN: %clang_cc1 -fsyntax-only -std=c++1y %s -verify void print(); @@ -56,3 +57,25 @@ void variadic_lambda(Args... args) { } template void variadic_lambda(int*, float*, double*); + +template<typename ...Args> +void init_capture_pack_err(Args ...args) { + [as(args)...] {} (); // expected-error {{expected ','}} + [as...(args)]{} (); // expected-error {{expected ','}} +} + +template<typename ...Args> +void init_capture_pack_multi(Args ...args) { + [as(args...)] {} (); // expected-error {{initializer missing}} expected-error {{multiple}} +} +template void init_capture_pack_multi(); // expected-note {{instantiation}} +template void init_capture_pack_multi(int); +template void init_capture_pack_multi(int, int); // expected-note {{instantiation}} + +template<typename ...Args> +void init_capture_pack_outer(Args ...args) { + print([as(args)] { return sizeof(as); } () ...); +} +template void init_capture_pack_outer(); +template void init_capture_pack_outer(int); +template void init_capture_pack_outer(int, int); diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp index d1384f19dd1..408fb75f809 100644 --- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp +++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp @@ -26,4 +26,7 @@ void S2::f(int i) { (void)[=, this]{ }; // expected-error{{'this' cannot be explicitly captured}} (void)[=]{ this->g(i); }; (void)[i, i]{ }; // expected-error{{'i' can appear only once in a capture list}} + (void)[i(0), i(1)]{ }; // expected-error{{'i' can appear only once in a capture list}} + (void)[i, i(1)]{ }; // expected-error{{'i' can appear only once in a capture list}} + (void)[i(0), i]{ }; // expected-error{{'i' can appear only once in a capture list}} } |

