r183594 - Recursively lifetime-extend into array temporaries. These can get implicitly

Richard Smith richard-llvm at metafoo.co.uk
Fri Jun 7 17:02:08 PDT 2013


Author: rsmith
Date: Fri Jun  7 19:02:08 2013
New Revision: 183594

URL: http://llvm.org/viewvc/llvm-project?rev=183594&view=rev
Log:
Recursively lifetime-extend into array temporaries. These can get implicitly
created through binding a reference-to-array to an initializer list.

Modified:
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/test/CodeGenCXX/const-init-cxx11.cpp
    cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=183594&r1=183593&r2=183594&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Fri Jun  7 19:02:08 2013
@@ -3149,8 +3149,7 @@ static void TryReferenceListInitializati
                                            const InitializedEntity &Entity,
                                            const InitializationKind &Kind,
                                            InitListExpr *InitList,
-                                           InitializationSequence &Sequence)
-{
+                                           InitializationSequence &Sequence) {
   // First, catch C++03 where this isn't possible.
   if (!S.getLangOpts().CPlusPlus11) {
     Sequence.SetFailed(InitializationSequence::FK_ReferenceBindingToInitList);
@@ -5216,7 +5215,7 @@ static void performLifetimeExtension(Exp
       Init->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments));
 
   if (InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) {
-    if (ILE->initializesStdInitializerList()) {
+    if (ILE->initializesStdInitializerList() || ILE->getType()->isArrayType()) {
       // FIXME: If this is an InitListExpr which creates a std::initializer_list
       //        object, we also need to lifetime-extend the underlying array
       //        itself. Fix the representation to explicitly materialize an
@@ -5226,7 +5225,7 @@ static void performLifetimeExtension(Exp
       return;
     }
 
-    CXXRecordDecl *RD = Init->getType()->getAsCXXRecordDecl();
+    CXXRecordDecl *RD = ILE->getType()->getAsCXXRecordDecl();
     if (RD) {
       assert(RD->isAggregate() && "aggregate init on non-aggregate");
 

Modified: cfe/trunk/test/CodeGenCXX/const-init-cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/const-init-cxx11.cpp?rev=183594&r1=183593&r2=183594&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/const-init-cxx11.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/const-init-cxx11.cpp Fri Jun  7 19:02:08 2013
@@ -368,6 +368,17 @@ namespace PR13273 {
   extern const S s {};
 }
 
+namespace ArrayTemporary {
+  struct A { const int (&x)[3]; };
+  struct B { const A (&x)[2]; };
+  // CHECK: @[[A1:_ZGRN14ArrayTemporary1bE.*]] = private constant [3 x i32] [i32 1, i32 2, i32 3]
+  // CHECK: @[[A2:_ZGRN14ArrayTemporary1bE.*]] = private constant [3 x i32] [i32 4, i32 5, i32 6]
+  // CHECK: @[[ARR:_ZGRN14ArrayTemporary1bE.*]] = private constant [2 x {{.*}}] [{{.*}} { [3 x i32]* @[[A1]] }, {{.*}} { [3 x i32]* @[[A2]] }]
+  // CHECK: @[[B:_ZGRN14ArrayTemporary1bE.*]] = private global {{.*}} { [2 x {{.*}}]* @[[ARR]] }
+  // CHECK: @_ZN14ArrayTemporary1bE = constant {{.*}}* @[[B]]
+  B &&b = { { { { 1, 2, 3 } }, { { 4, 5, 6 } } } };
+}
+
 namespace UnemittedTemporaryDecl {
   constexpr int &&ref = 0;
   extern constexpr int &ref2 = ref;

Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=183594&r1=183593&r2=183594&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)
+++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Fri Jun  7 19:02:08 2013
@@ -373,6 +373,12 @@ namespace NestedNonStatic {
   constexpr B b = { A(A{0}) }; // expected-error {{constant expression}} expected-note {{reference to temporary}} expected-note {{here}}
 }
 
+namespace FakeInitList {
+  struct init_list_3_ints { const int (&x)[3]; };
+  struct init_list_2_init_list_3_ints { const init_list_3_ints (&x)[2]; };
+  constexpr init_list_2_init_list_3_ints ils = { { { { 1, 2, 3 } }, { { 4, 5, 6 } } } };
+}
+
 }
 
 constexpr int strcmp_ce(const char *p, const char *q) {





More information about the cfe-commits mailing list