Fix crash when constant-evaluating a CXXConstructExpr representing

value-initialization for an array of class type with a trivial default
constructor.

llvm-svn: 160024
This commit is contained in:
Richard Smith 2012-07-10 22:12:55 +00:00
parent eab627b951
commit 9fce7bc721
2 changed files with 17 additions and 8 deletions

View File

@ -3911,10 +3911,6 @@ bool ArrayExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
}
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 @@ bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E) {
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 @@ bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E) {
return true;
if (ZeroInit) {
ImplicitValueInitExpr VIE(CAT->getElementType());
ImplicitValueInitExpr VIE(ElemTy);
return EvaluateInPlace(*Value, Info, Subobject, &VIE);
}
@ -3963,7 +3964,7 @@ bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E) {
return false;
if (ZeroInit && !HadZeroInit) {
ImplicitValueInitExpr VIE(CAT->getElementType());
ImplicitValueInitExpr VIE(ElemTy);
if (!EvaluateInPlace(*Value, Info, Subobject, &VIE))
return false;
}

View File

@ -507,6 +507,14 @@ static_assert(selfref[1][0][1] == 3, "");
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 {