@@ -8593,6 +8593,10 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
85938593static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This,
85948594 APValue &Result, const InitListExpr *ILE,
85958595 QualType AllocType);
8596+ static bool EvaluateArrayNewConstructExpr(EvalInfo &Info, LValue &This,
8597+ APValue &Result,
8598+ const CXXConstructExpr *CCE,
8599+ QualType AllocType);
85968600
85978601bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
85988602 if (!Info.getLangOpts().CPlusPlus2a)
@@ -8642,6 +8646,7 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
86428646
86438647 const Expr *Init = E->getInitializer();
86448648 const InitListExpr *ResizedArrayILE = nullptr;
8649+ const CXXConstructExpr *ResizedArrayCCE = nullptr;
86458650
86468651 QualType AllocType = E->getAllocatedType();
86478652 if (Optional<const Expr*> ArraySize = E->getArraySize()) {
@@ -8685,7 +8690,7 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
86858690 // -- the new-initializer is a braced-init-list and the number of
86868691 // array elements for which initializers are provided [...]
86878692 // exceeds the number of elements to initialize
8688- if (Init) {
8693+ if (Init && !isa<CXXConstructExpr>(Init) ) {
86898694 auto *CAT = Info.Ctx.getAsConstantArrayType(Init->getType());
86908695 assert(CAT && "unexpected type for array initializer");
86918696
@@ -8708,6 +8713,8 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
87088713 // special handling for this case when we initialize.
87098714 if (InitBound != AllocBound)
87108715 ResizedArrayILE = cast<InitListExpr>(Init);
8716+ } else if (Init) {
8717+ ResizedArrayCCE = cast<CXXConstructExpr>(Init);
87118718 }
87128719
87138720 AllocType = Info.Ctx.getConstantArrayType(AllocType, ArrayBound, nullptr,
@@ -8772,6 +8779,10 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
87728779 if (!EvaluateArrayNewInitList(Info, Result, *Val, ResizedArrayILE,
87738780 AllocType))
87748781 return false;
8782+ } else if (ResizedArrayCCE) {
8783+ if (!EvaluateArrayNewConstructExpr(Info, Result, *Val, ResizedArrayCCE,
8784+ AllocType))
8785+ return false;
87758786 } else if (Init) {
87768787 if (!EvaluateInPlace(*Val, Info, Result, Init))
87778788 return false;
@@ -9597,6 +9608,16 @@ static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This,
95979608 .VisitInitListExpr(ILE, AllocType);
95989609}
95999610
9611+ static bool EvaluateArrayNewConstructExpr(EvalInfo &Info, LValue &This,
9612+ APValue &Result,
9613+ const CXXConstructExpr *CCE,
9614+ QualType AllocType) {
9615+ assert(CCE->isRValue() && CCE->getType()->isArrayType() &&
9616+ "not an array rvalue");
9617+ return ArrayExprEvaluator(Info, This, Result)
9618+ .VisitCXXConstructExpr(CCE, This, &Result, AllocType);
9619+ }
9620+
96009621// Return true iff the given array filler may depend on the element index.
96019622static bool MaybeElementDependentArrayFiller(const Expr *FillerExpr) {
96029623 // For now, just whitelist non-class value-initialization and initialization
0 commit comments