summaryrefslogtreecommitdiffstats
path: root/test/CXX/expr/expr.prim/expr.prim.lambda
diff options
context:
space:
mode:
Diffstat (limited to 'test/CXX/expr/expr.prim/expr.prim.lambda')
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mm2
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/generic-lambda-unimplemented-1y.cpp31
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/p11-1y.cpp77
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp12
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/p2-generic-lambda-1y.cpp25
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/p2.cpp2
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp25
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/p4-1y.cpp66
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp8
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/p4.mm2
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/p5-generic-lambda-1y.cpp131
-rw-r--r--test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp5
12 files changed, 379 insertions, 7 deletions
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mm b/test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mm
index 9f98671..24ce2cd 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mm
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mm
@@ -14,7 +14,7 @@ namespace PR12746 {
}
// CHECK: define internal zeroext i1 @___ZN7PR127462f1EPi_block_invoke
- // CHECK: call zeroext i1 @"_ZNK7PR127462f132___ZN7PR127462f1EPi_block_invoke3$_0clEv"
+ // CHECK: call zeroext i1 @"_ZZZN7PR127462f1EPiEUb_ENK3$_0clEv"
bool f2(int *x) {
auto outer = [&]() -> bool {
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/generic-lambda-unimplemented-1y.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/generic-lambda-unimplemented-1y.cpp
new file mode 100644
index 0000000..7f42c39
--- /dev/null
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/generic-lambda-unimplemented-1y.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++1y %s -verify
+//expected-no-diagnostics
+namespace lambda_capturing {
+// FIXME: Once return type deduction is implemented for generic lambdas
+// this will need to be updated.
+void test() {
+ int i = 10;
+ {
+ auto L = [=](auto a) -> int {
+ return i + a;
+ };
+ L(3);
+ }
+ {
+ auto L = [i](auto a) -> int {
+ return i + a;
+ };
+ L(3);
+ }
+ {
+ auto L = [i=i](auto a) -> int {
+ return i + a;
+ };
+ L(3);
+ }
+
+
+}
+
+}
+
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p11-1y.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p11-1y.cpp
new file mode 100644
index 0000000..6be200d
--- /dev/null
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p11-1y.cpp
@@ -0,0 +1,77 @@
+// RUN: %clang_cc1 -std=c++1y %s -verify
+
+const char *has_no_member = [x("hello")] {}.x; // expected-error {{no member named 'x'}}
+
+double f;
+auto with_float = [f(1.0f)] {
+ using T = decltype(f);
+ using T = float;
+};
+auto with_float_2 = [&f(f)] { // ok, refers to outer f
+ using T = decltype(f);
+ using T = double&;
+};
+
+// Within the lambda-expression's 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) { // outer c, not init-capture
+ 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 {{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) { (void)[a(t...)] {}; } // expected-error {{initializer missing for lambda capture 'a'}}
+template void pack_1<>(); // expected-note {{instantiation of}}
+
+// FIXME: Might need lifetime extension for the temporary here.
+// See DR1695.
+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()))] {};
+
+template<typename T> T instantiate_test(T t) {
+ [x(&t)]() { *x = 1; } (); // expected-error {{assigning to 'const char *'}}
+ return t;
+}
+int instantiate_test_1 = instantiate_test(0);
+const char *instantiate_test_2 = instantiate_test("foo"); // expected-note {{here}}
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp
index 6358215..2ddcf18 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp
@@ -88,3 +88,15 @@ struct CaptureArrayAndThis {
}
};
+namespace rdar14468891 {
+ class X {
+ public:
+ virtual ~X() = 0; // expected-note{{unimplemented pure virtual method '~X' in 'X'}}
+ };
+
+ class Y : public X { };
+
+ void capture(X &x) {
+ [x]() {}(); // expected-error{{by-copy capture of value of abstract type 'rdar14468891::X'}}
+ }
+}
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p2-generic-lambda-1y.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p2-generic-lambda-1y.cpp
new file mode 100644
index 0000000..d41c450
--- /dev/null
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p2-generic-lambda-1y.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1y -DCXX1Y
+
+// prvalue
+void prvalue() {
+ auto&& x = [](auto a)->void { };
+ auto& y = [](auto *a)->void { }; // expected-error{{cannot bind to a temporary of type}}
+}
+
+namespace std {
+ class type_info;
+}
+
+struct P {
+ virtual ~P();
+};
+
+void unevaluated_operand(P &p, int i) { //expected-note{{declared here}}
+ // FIXME: this should only emit one error.
+ int i2 = sizeof([](auto a, auto b)->void{}(3, '4')); // expected-error{{lambda expression in an unevaluated operand}} \
+ // expected-error{{invalid application of 'sizeof'}}
+ const std::type_info &ti1 = typeid([](auto &a) -> P& { static P p; return p; }(i));
+ const std::type_info &ti2 = typeid([](auto) -> int { return i; }(i)); // expected-error{{lambda expression in an unevaluated operand}}\
+ // expected-error{{cannot be implicitly captured}}\
+ // expected-note{{begins here}}
+}
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p2.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p2.cpp
index c6ed308d..1fbe287 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p2.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p2.cpp
@@ -15,7 +15,7 @@ struct P {
};
void unevaluated_operand(P &p, int i) {
- int i2 = sizeof([]()->void{}()); // expected-error{{lambda expression in an unevaluated operand}}
+ int i2 = sizeof([] ()->int { return 0; }()); // expected-error{{lambda expression in an unevaluated operand}}
const std::type_info &ti1 = typeid([&]() -> P& { return p; }());
const std::type_info &ti2 = typeid([&]() -> int { return i; }()); // expected-error{{lambda expression in an unevaluated operand}}
}
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp
index 82fc04a..4ae34de 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp
+++ b/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++11 %s -verify -Wno-c++1y-extensions
+// 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 for lambda capture 'as'}} 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/test/CXX/expr/expr.prim/expr.prim.lambda/p4-1y.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p4-1y.cpp
new file mode 100644
index 0000000..f846133
--- /dev/null
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p4-1y.cpp
@@ -0,0 +1,66 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++1y %s -verify
+
+int a;
+int &b = [] (int &r) -> decltype(auto) { return r; } (a);
+int &c = [] (int &r) -> decltype(auto) { return (r); } (a);
+int &d = [] (int &r) -> auto & { return r; } (a);
+int &e = [] (int &r) -> auto { return r; } (a); // expected-error {{cannot bind to a temporary}}
+int &f = [] (int r) -> decltype(auto) { return r; } (a); // expected-error {{cannot bind to a temporary}}
+int &g = [] (int r) -> decltype(auto) { return (r); } (a); // expected-warning {{reference to stack}}
+
+
+int test_explicit_auto_return()
+{
+ struct X {};
+ auto L = [](auto F, auto a) { return F(a); };
+ auto M = [](auto a) -> auto { return a; }; // OK
+ auto MRef = [](auto b) -> auto& { return b; }; //expected-warning{{reference to stack}}
+ auto MPtr = [](auto c) -> auto* { return &c; }; //expected-warning{{address of stack}}
+ auto MDeclType = [](auto&& d) -> decltype(auto) { return static_cast<decltype(d)>(d); }; //OK
+ M(3);
+
+ auto &&x = MDeclType(X{});
+ auto &&x1 = M(X{});
+ auto &&x2 = MRef(X{});//expected-note{{in instantiation of}}
+ auto &&x3 = MPtr(X{}); //expected-note{{in instantiation of}}
+ return 0;
+}
+
+int test_implicit_auto_return()
+{
+ {
+ auto M = [](auto a) { return a; };
+ struct X {};
+ X x = M(X{});
+
+ }
+}
+
+int test_multiple_returns() {
+ auto M = [](auto a) {
+ bool k;
+ if (k)
+ return a;
+ else
+ return 5; //expected-error{{deduced as 'int' here}}
+ };
+ M(3); // OK
+ M('a'); //expected-note{{in instantiation of}}
+ return 0;
+}
+int test_no_parameter_list()
+{
+ static int si = 0;
+ auto M = [] { return 5; }; // OK
+ auto M2 = [] -> auto&& { return si; }; // expected-error{{lambda requires '()'}}
+ M();
+}
+
+int test_conditional_in_return() {
+ auto Fac = [](auto f, auto n) {
+ return n <= 0 ? n : f(f, n - 1) * n;
+ };
+ // FIXME: this test causes a recursive limit - need to error more gracefully.
+ //Fac(Fac, 3);
+
+} \ No newline at end of file
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp
index f580e7e..1016cb1 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p4.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 -DCPP1Y
void missing_lambda_declarator() {
[](){}();
@@ -17,7 +18,7 @@ void infer_void_return_type(int i) {
switch (x) {
case 0: return get<void>();
case 1: return;
- case 2: return { 1, 2.0 }; // expected-error{{cannot deduce lambda return type from initializer list}}
+ case 2: return { 1, 2.0 }; //expected-error{{cannot deduce}}
}
}(7);
}
@@ -38,7 +39,10 @@ X infer_X_return_type_fail(X x) {
if (y > 0)
return X();
else
- return x; // expected-error{{return type 'const X' must match previous return type 'X' when lambda expression has unspecified explicit return type}}
+ return x;
+#if __cplusplus <= 201103L
+ // expected-error@-2 {{return type 'const X' must match previous return type 'X' when lambda expression has unspecified explicit return type}}
+#endif
}(5);
}
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p4.mm b/test/CXX/expr/expr.prim/expr.prim.lambda/p4.mm
index 0126e23..92c6290 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p4.mm
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p4.mm
@@ -4,5 +4,5 @@
@end
void test_result_type() {
- auto l1 = [] () -> A { }; // expected-error{{non-pointer Objective-C class type 'A' in lambda expression result}}
+ auto l1 = [] () -> A { }; // expected-error{{interface type 'A' cannot be returned by value; did you forget * in 'A'?}}
}
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p5-generic-lambda-1y.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p5-generic-lambda-1y.cpp
new file mode 100644
index 0000000..c5d3bf6
--- /dev/null
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p5-generic-lambda-1y.cpp
@@ -0,0 +1,131 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1y -DCXX1Y
+
+namespace test_factorial {
+
+auto Fact = [](auto Self, unsigned n) -> unsigned {
+ return !n ? 1 : Self(Self, n - 1) * n;
+};
+
+auto six = Fact(Fact, 3);
+
+}
+
+namespace overload_generic_lambda {
+ template <class F1, class F2> struct overload : F1, F2 {
+ using F1::operator();
+ using F2::operator();
+ overload(F1 f1, F2 f2) : F1(f1), F2(f2) { }
+ };
+
+ auto NumParams = [](auto Self, auto h, auto ... rest) -> unsigned {
+ return 1 + Self(Self, rest...);
+ };
+ auto Base = [](auto Self, auto h) -> unsigned {
+ return 1;
+ };
+ overload<decltype(Base), decltype(NumParams)> O(Base, NumParams);
+ int num_params = O(O, 5, 3, "abc", 3.14, 'a');
+}
+
+
+namespace overload_generic_lambda_return_type_deduction {
+ template <class F1, class F2> struct overload : F1, F2 {
+ using F1::operator();
+ using F2::operator();
+ overload(F1 f1, F2 f2) : F1(f1), F2(f2) { }
+ };
+
+ auto NumParams = [](auto Self, auto h, auto ... rest) {
+ return 1 + Self(Self, rest...);
+ };
+ auto Base = [](auto Self, auto h) {
+ return 1;
+ };
+ overload<decltype(Base), decltype(NumParams)> O(Base, NumParams);
+ int num_params = O(O, 5, 3, "abc", 3.14, 'a');
+}
+
+namespace test_standard_p5 {
+// FIXME: This test should eventually compile without an explicit trailing return type
+auto glambda = [](auto a, auto&& b) ->bool { return a < b; };
+bool b = glambda(3, 3.14); // OK
+
+}
+namespace test_deduction_failure {
+ int test() {
+ auto g = [](auto *a) { //expected-note{{candidate template ignored}}
+ return a;
+ };
+ struct X { };
+ X *x;
+ g(x);
+ g(3); //expected-error{{no matching function}}
+ return 0;
+ }
+
+}
+
+namespace test_instantiation_or_sfinae_failure {
+int test2() {
+ {
+ auto L = [](auto *a) {
+ return (*a)(a); }; //expected-error{{called object type 'double' is not a function}}
+ double d;
+ L(&d); //expected-note{{in instantiation of}}
+ auto M = [](auto b) { return b; };
+ L(&M); // ok
+ }
+ {
+ auto L = [](auto *a) ->decltype (a->foo()) { //expected-note2{{candidate template ignored:}}
+ return (*a)(a); };
+ double d;
+ L(&d); //expected-error{{no matching function for call}}
+ auto M = [](auto b) { return b; };
+ L(&M); //expected-error{{no matching function for call}}
+
+ }
+ return 0;
+}
+
+
+}
+
+namespace test_misc {
+auto GL = [](auto a, decltype(a) b) //expected-note{{candidate function}}
+ -> int { return a + b; };
+
+void test() {
+ struct X { };
+ GL(3, X{}); //expected-error{{no matching function}}
+}
+
+void test2() {
+ auto l = [](auto *a) -> int {
+ (*a)(a); return 0; }; //expected-error{{called object type 'double' is not a function}}
+ l(&l);
+ double d;
+ l(&d); //expected-note{{in instantiation of}}
+}
+
+}
+
+namespace nested_lambdas {
+ int test() {
+ auto L = [](auto a) {
+ return [=](auto b) {
+ return a + b;
+ };
+ };
+ }
+ auto get_lambda() {
+ return [](auto a) {
+ return a;
+ };
+ };
+
+ int test2() {
+ auto L = get_lambda();
+ L(3);
+ }
+}
+
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp
index d1384f1..b9b8cd7 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p8.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 %s -verify
+// RUN: %clang_cc1 -std=c++11 %s -verify -Wno-c++1y-extensions
class X0 {
void explicit_capture() {
@@ -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}}
}
OpenPOWER on IntegriCloud