From: Richard Smith Date: Tue, 7 Oct 2014 18:01:33 +0000 (+0000) Subject: PR21180: Lambda closure types are neither aggregates nor literal types. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=45991fc3792a1a9a8f3cdf6bd0ba4309a8225ddb;p=clang PR21180: Lambda closure types are neither aggregates nor literal types. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@219222 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 7ebd0e251c..98efa6c5b6 100644 --- a/include/clang/AST/DeclCXX.h +++ b/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/test/CXX/expr/expr.const/p2-0x.cpp b/test/CXX/expr/expr.const/p2-0x.cpp index bcf45a0c05..249e552724 100644 --- a/test/CXX/expr/expr.const/p2-0x.cpp +++ b/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/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp index 562f92a78b..c0fa72ba42 100644 --- a/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp +++ b/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/test/SemaCXX/cxx1y-generic-lambdas.cpp b/test/SemaCXX/cxx1y-generic-lambdas.cpp index dc8574825d..8e07b806b1 100644 --- a/test/SemaCXX/cxx1y-generic-lambdas.cpp +++ b/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; }) { }