erik.pilkington created this revision.

Previously, clang would assert on the following:

  struct S {
    constexpr S (const int& ir = 0) {}
  };
  constexpr S foo[2];

The problem was that while initializing foo, CallStackFrame::createTemporary() 
was called twice for the MaterializeTemporaryExpr for `0` in the default 
constructor (once for each array element) without ending the lifetime of the 
first. This caused createTemporary() to assert. This patch fixes this problem 
by separating the lifetime of temporaries created for successive calls to the 
ctor when initializing arrays.

https://bugs.llvm.org/show_bug.cgi?id=34858

Thanks for taking a look!
Erik


https://reviews.llvm.org/D40372

Files:
  lib/AST/ExprConstant.cpp
  test/SemaCXX/constant-expression-cxx1y.cpp


Index: test/SemaCXX/constant-expression-cxx1y.cpp
===================================================================
--- test/SemaCXX/constant-expression-cxx1y.cpp
+++ test/SemaCXX/constant-expression-cxx1y.cpp
@@ -1021,3 +1021,10 @@
 }
 static_assert(evalNested(), "");
 } // namespace PR19741
+
+namespace PR34858 {
+struct S {
+  constexpr S(const int & = 0) {}
+};
+constexpr S s[2];
+}
Index: lib/AST/ExprConstant.cpp
===================================================================
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -6912,12 +6912,14 @@
     // Initialize the elements.
     LValue ArrayElt = Subobject;
     ArrayElt.addArray(Info, E, CAT);
-    for (unsigned I = 0; I != N; ++I)
+    for (unsigned I = 0; I != N; ++I) {
+      BlockScopeRAII Scope(Info);
       if (!VisitCXXConstructExpr(E, ArrayElt, 
&Value->getArrayInitializedElt(I),
                                  CAT->getElementType()) ||
           !HandleLValueArrayAdjustment(Info, E, ArrayElt,
                                        CAT->getElementType(), 1))
         return false;
+    }
 
     return true;
   }


Index: test/SemaCXX/constant-expression-cxx1y.cpp
===================================================================
--- test/SemaCXX/constant-expression-cxx1y.cpp
+++ test/SemaCXX/constant-expression-cxx1y.cpp
@@ -1021,3 +1021,10 @@
 }
 static_assert(evalNested(), "");
 } // namespace PR19741
+
+namespace PR34858 {
+struct S {
+  constexpr S(const int & = 0) {}
+};
+constexpr S s[2];
+}
Index: lib/AST/ExprConstant.cpp
===================================================================
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -6912,12 +6912,14 @@
     // Initialize the elements.
     LValue ArrayElt = Subobject;
     ArrayElt.addArray(Info, E, CAT);
-    for (unsigned I = 0; I != N; ++I)
+    for (unsigned I = 0; I != N; ++I) {
+      BlockScopeRAII Scope(Info);
       if (!VisitCXXConstructExpr(E, ArrayElt, &Value->getArrayInitializedElt(I),
                                  CAT->getElementType()) ||
           !HandleLValueArrayAdjustment(Info, E, ArrayElt,
                                        CAT->getElementType(), 1))
         return false;
+    }
 
     return true;
   }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D40372: [ExprConst... Erik Pilkington via Phabricator via cfe-commits

Reply via email to