Fix crash when constant-evaluating a CXXConstructExpr representing
value-initialization for an array of class type with a trivial default
constructor.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160024 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index f9583de..ad5aa54 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -3911,10 +3911,6 @@
}
bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E) {
- const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(E->getType());
- if (!CAT)
- return Error(E);
-
// FIXME: The Subobject here isn't necessarily right. This rarely matters,
// but sometimes does:
// struct S { constexpr S() : p(&p) {} void *p; };
@@ -3923,17 +3919,22 @@
APValue *Value = &Result;
bool HadZeroInit = true;
- while (CAT) {
+ QualType ElemTy = E->getType();
+ while (const ConstantArrayType *CAT =
+ Info.Ctx.getAsConstantArrayType(ElemTy)) {
Subobject.addArray(Info, E, CAT);
HadZeroInit &= !Value->isUninit();
if (!HadZeroInit)
*Value = APValue(APValue::UninitArray(), 0, CAT->getSize().getZExtValue());
if (!Value->hasArrayFiller())
return true;
- CAT = Info.Ctx.getAsConstantArrayType(CAT->getElementType());
Value = &Value->getArrayFiller();
+ ElemTy = CAT->getElementType();
}
+ if (!ElemTy->isRecordType())
+ return Error(E);
+
const CXXConstructorDecl *FD = E->getConstructor();
bool ZeroInit = E->requiresZeroInitialization();
@@ -3942,7 +3943,7 @@
return true;
if (ZeroInit) {
- ImplicitValueInitExpr VIE(CAT->getElementType());
+ ImplicitValueInitExpr VIE(ElemTy);
return EvaluateInPlace(*Value, Info, Subobject, &VIE);
}
@@ -3963,7 +3964,7 @@
return false;
if (ZeroInit && !HadZeroInit) {
- ImplicitValueInitExpr VIE(CAT->getElementType());
+ ImplicitValueInitExpr VIE(ElemTy);
if (!EvaluateInPlace(*Value, Info, Subobject, &VIE))
return false;
}
diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp
index f576dfa..2b9a4ad 100644
--- a/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/test/SemaCXX/constant-expression-cxx11.cpp
@@ -507,6 +507,14 @@
static_assert(selfref[1][1][0] == 0, "");
static_assert(selfref[1][1][1] == 0, "");
+struct TrivialDefCtor { int n; };
+typedef TrivialDefCtor TDCArray[2][2];
+static_assert(TDCArray{}[1][1].n == 0, "");
+
+struct NonAggregateTDC : TrivialDefCtor {};
+typedef NonAggregateTDC NATDCArray[2][2];
+static_assert(NATDCArray{}[1][1].n == 0, "");
+
}
namespace DependentValues {