r219222 - PR21180: Lambda closure types are neither aggregates nor literal types.

Richard Smith richard-llvm at metafoo.co.uk
Tue Oct 7 11:01:33 PDT 2014


Author: rsmith
Date: Tue Oct  7 13:01:33 2014
New Revision: 219222

URL: http://llvm.org/viewvc/llvm-project?rev=219222&view=rev
Log:
PR21180: Lambda closure types are neither aggregates nor literal types.

Modified:
    cfe/trunk/include/clang/AST/DeclCXX.h
    cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp
    cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp
    cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=219222&r1=219221&r2=219222&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Tue Oct  7 13:01:33 2014
@@ -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

Modified: cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp?rev=219222&r1=219221&r2=219222&view=diff
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp Tue Oct  7 13:01:33 2014
@@ -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

Modified: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp?rev=219222&r1=219221&r2=219222&view=diff
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p3.cpp Tue Oct  7 13:01:33 2014
@@ -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)), "");
 }

Modified: cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp?rev=219222&r1=219221&r2=219222&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp Tue Oct  7 13:01:33 2014
@@ -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; }) { }





More information about the cfe-commits mailing list