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..2b9a4adf 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 {