[c++2a] Fix assertion failure if we would walk over more than one level
authorRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 30 May 2019 20:45:12 +0000 (20:45 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 30 May 2019 20:45:12 +0000 (20:45 +0000)
of derived-to-base conversion path when implicitly starting union
subobject lifetimes in constant evaluation.

llvm-svn: 362147

clang/lib/AST/ExprConstant.cpp
clang/test/SemaCXX/constant-expression-cxx2a.cpp

index ac21b63..df9b306 100644 (file)
@@ -5031,7 +5031,8 @@ static bool HandleUnionActiveMemberChange(EvalInfo &Info, const Expr *LHSExpr,
       if (ICE->getCastKind() != CK_DerivedToBase &&
           ICE->getCastKind() != CK_UncheckedDerivedToBase)
         break;
-      for (const CXXBaseSpecifier *Elt : ICE->path()) {
+      // Walk path backwards as we walk up from the base to the derived class.
+      for (const CXXBaseSpecifier *Elt : llvm::reverse(ICE->path())) {
         --PathLength;
         (void)Elt;
         assert(declaresSameEntity(Elt->getType()->getAsCXXRecordDecl(),
index aa534ce..f29f4be 100644 (file)
@@ -521,4 +521,14 @@ namespace Union {
     u1 = u2;
     return true;
   }();
+
+  struct S1 {
+    int n;
+  };
+  struct S2 : S1 {};
+  struct S3 : S2 {};
+  void f() {
+    S3 s;
+    s.n = 0;
+  }
 }