summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-10-07 18:01:33 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-10-07 18:01:33 +0000
commit640775b4282e68ba94efd8863a011d4065cf444f (patch)
tree81c3f92b18ef4d9a7b69c2a0cb11d34361ed4ef2
parent25d3c1cf614c3f295ca2c2579ce57145051a4a99 (diff)
downloadbcm5719-llvm-640775b4282e68ba94efd8863a011d4065cf444f.tar.gz
bcm5719-llvm-640775b4282e68ba94efd8863a011d4065cf444f.zip
PR21180: Lambda closure types are neither aggregates nor literal types.
llvm-svn: 219222
-rw-r--r--clang/include/clang/AST/DeclCXX.h6
-rw-r--r--clang/test/CXX/expr/expr.const/p2-0x.cpp2
-rw-r--r--clang/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp5
-rw-r--r--clang/test/SemaCXX/cxx1y-generic-lambdas.cpp19
4 files changed, 24 insertions, 8 deletions
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h
index 7ebd0e251c7..98efa6c5b6c 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -538,6 +538,12 @@ class CXXRecordDecl : public RecordDecl {
ManglingNumber(0), ContextDecl(nullptr), Captures(nullptr),
MethodTyInfo(Info) {
IsLambda = true;
+
+ // C++11 [expr.prim.lambda]p3:
+ // This class type is neither an aggregate nor a literal type.
+ Aggregate = false;
+ PlainOldData = false;
+ HasNonLiteralTypeFieldsOrBases = true;
}
/// \brief Whether this lambda is known to be dependent, even if its
diff --git a/clang/test/CXX/expr/expr.const/p2-0x.cpp b/clang/test/CXX/expr/expr.const/p2-0x.cpp
index bcf45a0c05b..249e5527243 100644
--- a/clang/test/CXX/expr/expr.const/p2-0x.cpp
+++ b/clang/test/CXX/expr/expr.const/p2-0x.cpp
@@ -277,7 +277,7 @@ namespace UndefinedBehavior {
// - a lambda-expression (5.1.2);
struct Lambda {
- int n : []{ return 1; }(); // expected-error {{constant expression}} expected-error {{integral constant expression}}
+ int n : []{ return 1; }(); // expected-error {{constant expression}} expected-error {{integral constant expression}} expected-note {{non-literal type}}
};
// - an lvalue-to-rvalue conversion (4.1) unless it is applied to
diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp
index 562f92a78bb..c0fa72ba42f 100644
--- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp
@@ -3,4 +3,9 @@
void test_nonaggregate(int i) {
auto lambda = [i]() -> void {}; // expected-note 3{{candidate constructor}}
decltype(lambda) foo = { 1 }; // expected-error{{no matching constructor}}
+ static_assert(!__is_literal(decltype(lambda)), "");
+
+ auto lambda2 = []{}; // expected-note {{lambda}}
+ decltype(lambda2) bar = {}; // expected-error{{call to implicitly-deleted default constructor}}
+ static_assert(!__is_literal(decltype(lambda2)), "");
}
diff --git a/clang/test/SemaCXX/cxx1y-generic-lambdas.cpp b/clang/test/SemaCXX/cxx1y-generic-lambdas.cpp
index dc8574825dd..8e07b806b1c 100644
--- a/clang/test/SemaCXX/cxx1y-generic-lambdas.cpp
+++ b/clang/test/SemaCXX/cxx1y-generic-lambdas.cpp
@@ -859,11 +859,13 @@ namespace ns1 {
struct X1 {
struct X2 {
enum { E = [](auto i) { return i; }(3) }; //expected-error{{inside of a constant expression}}\
- //expected-error{{not an integral constant}}
+ //expected-error{{not an integral constant}}\
+ //expected-note{{non-literal type}}
int L = ([] (int i) { return i; })(2);
void foo(int i = ([] (int i) { return i; })(2)) { }
int B : ([](int i) { return i; })(3); //expected-error{{inside of a constant expression}}\
- //expected-error{{not an integral constant}}
+ //expected-error{{not an integral constant}}\
+ //expected-note{{non-literal type}}
int arr[([](int i) { return i; })(3)]; //expected-error{{inside of a constant expression}}\
//expected-error{{must have a constant size}}
int (*fp)(int) = [](int i) { return i; };
@@ -871,9 +873,10 @@ struct X1 {
int L2 = ([](auto i) { return i; })(2);
void fooG(int i = ([] (auto i) { return i; })(2)) { }
int BG : ([](auto i) { return i; })(3); //expected-error{{inside of a constant expression}} \
- //expected-error{{not an integral constant}}
+ //expected-error{{not an integral constant}}\
+ //expected-note{{non-literal type}}
int arrG[([](auto i) { return i; })(3)]; //expected-error{{inside of a constant expression}}\
- //expected-error{{must have a constant size}}
+ //expected-error{{must have a constant size}}
int (*fpG)(int) = [](auto i) { return i; };
void fooptrG(int (*fp)(char) = [](auto c) { return 0; }) { }
};
@@ -887,14 +890,16 @@ struct X1 {
int L = ([] (T i) { return i; })(2);
void foo(int i = ([] (int i) { return i; })(2)) { }
int B : ([](T i) { return i; })(3); //expected-error{{inside of a constant expression}}\
- //expected-error{{not an integral constant}}
+ //expected-error{{not an integral constant}}\
+ //expected-note{{non-literal type}}
int arr[([](T i) { return i; })(3)]; //expected-error{{inside of a constant expression}}\
- //expected-error{{must have a constant size}}
+ //expected-error{{must have a constant size}}
int (*fp)(T) = [](T i) { return i; };
void fooptr(T (*fp)(char) = [](char c) { return 0; }) { }
int L2 = ([](auto i) { return i; })(2);
void fooG(T i = ([] (auto i) { return i; })(2)) { }
- int BG : ([](auto i) { return i; })(3); //expected-error{{not an integral constant}}
+ int BG : ([](auto i) { return i; })(3); //expected-error{{not an integral constant}}\
+ //expected-note{{non-literal type}}
int arrG[([](auto i) { return i; })(3)]; //expected-error{{must have a constant size}}
int (*fpG)(T) = [](auto i) { return i; };
void fooptrG(T (*fp)(char) = [](auto c) { return 0; }) { }
OpenPOWER on IntegriCloud