@@ -8677,6 +8677,10 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
86778677static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This,
86788678 APValue &Result, const InitListExpr *ILE,
86798679 QualType AllocType);
8680+ static bool EvaluateArrayNewConstructExpr(EvalInfo &Info, LValue &This,
8681+ APValue &Result,
8682+ const CXXConstructExpr *CCE,
8683+ QualType AllocType);
86808684
86818685bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
86828686 if (!Info.getLangOpts().CPlusPlus2a)
@@ -8726,6 +8730,7 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
87268730
87278731 const Expr *Init = E->getInitializer();
87288732 const InitListExpr *ResizedArrayILE = nullptr;
8733+ const CXXConstructExpr *ResizedArrayCCE = nullptr;
87298734
87308735 QualType AllocType = E->getAllocatedType();
87318736 if (Optional<const Expr*> ArraySize = E->getArraySize()) {
@@ -8769,7 +8774,7 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
87698774 // -- the new-initializer is a braced-init-list and the number of
87708775 // array elements for which initializers are provided [...]
87718776 // exceeds the number of elements to initialize
8772- if (Init) {
8777+ if (Init && !isa<CXXConstructExpr>(Init) ) {
87738778 auto *CAT = Info.Ctx.getAsConstantArrayType(Init->getType());
87748779 assert(CAT && "unexpected type for array initializer");
87758780
@@ -8792,6 +8797,8 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
87928797 // special handling for this case when we initialize.
87938798 if (InitBound != AllocBound)
87948799 ResizedArrayILE = cast<InitListExpr>(Init);
8800+ } else if (Init) {
8801+ ResizedArrayCCE = cast<CXXConstructExpr>(Init);
87958802 }
87968803
87978804 AllocType = Info.Ctx.getConstantArrayType(AllocType, ArrayBound, nullptr,
@@ -8856,6 +8863,10 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
88568863 if (!EvaluateArrayNewInitList(Info, Result, *Val, ResizedArrayILE,
88578864 AllocType))
88588865 return false;
8866+ } else if (ResizedArrayCCE) {
8867+ if (!EvaluateArrayNewConstructExpr(Info, Result, *Val, ResizedArrayCCE,
8868+ AllocType))
8869+ return false;
88598870 } else if (Init) {
88608871 if (!EvaluateInPlace(*Val, Info, Result, Init))
88618872 return false;
@@ -9683,6 +9694,16 @@ static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This,
96839694 .VisitInitListExpr(ILE, AllocType);
96849695}
96859696
9697+ static bool EvaluateArrayNewConstructExpr(EvalInfo &Info, LValue &This,
9698+ APValue &Result,
9699+ const CXXConstructExpr *CCE,
9700+ QualType AllocType) {
9701+ assert(CCE->isRValue() && CCE->getType()->isArrayType() &&
9702+ "not an array rvalue");
9703+ return ArrayExprEvaluator(Info, This, Result)
9704+ .VisitCXXConstructExpr(CCE, This, &Result, AllocType);
9705+ }
9706+
96869707// Return true iff the given array filler may depend on the element index.
96879708static bool MaybeElementDependentArrayFiller(const Expr *FillerExpr) {
96889709 // For now, just whitelist non-class value-initialization and initialization
0 commit comments