@@ -8593,6 +8593,10 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
8593
8593
static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This,
8594
8594
APValue &Result, const InitListExpr *ILE,
8595
8595
QualType AllocType);
8596
+ static bool EvaluateArrayNewConstructExpr(EvalInfo &Info, LValue &This,
8597
+ APValue &Result,
8598
+ const CXXConstructExpr *CCE,
8599
+ QualType AllocType);
8596
8600
8597
8601
bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
8598
8602
if (!Info.getLangOpts().CPlusPlus2a)
@@ -8642,6 +8646,7 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
8642
8646
8643
8647
const Expr *Init = E->getInitializer();
8644
8648
const InitListExpr *ResizedArrayILE = nullptr;
8649
+ const CXXConstructExpr *ResizedArrayCCE = nullptr;
8645
8650
8646
8651
QualType AllocType = E->getAllocatedType();
8647
8652
if (Optional<const Expr*> ArraySize = E->getArraySize()) {
@@ -8685,7 +8690,7 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
8685
8690
// -- the new-initializer is a braced-init-list and the number of
8686
8691
// array elements for which initializers are provided [...]
8687
8692
// exceeds the number of elements to initialize
8688
- if (Init) {
8693
+ if (Init && !isa<CXXConstructExpr>(Init) ) {
8689
8694
auto *CAT = Info.Ctx.getAsConstantArrayType(Init->getType());
8690
8695
assert(CAT && "unexpected type for array initializer");
8691
8696
@@ -8708,6 +8713,8 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
8708
8713
// special handling for this case when we initialize.
8709
8714
if (InitBound != AllocBound)
8710
8715
ResizedArrayILE = cast<InitListExpr>(Init);
8716
+ } else if (Init) {
8717
+ ResizedArrayCCE = cast<CXXConstructExpr>(Init);
8711
8718
}
8712
8719
8713
8720
AllocType = Info.Ctx.getConstantArrayType(AllocType, ArrayBound, nullptr,
@@ -8772,6 +8779,10 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
8772
8779
if (!EvaluateArrayNewInitList(Info, Result, *Val, ResizedArrayILE,
8773
8780
AllocType))
8774
8781
return false;
8782
+ } else if (ResizedArrayCCE) {
8783
+ if (!EvaluateArrayNewConstructExpr(Info, Result, *Val, ResizedArrayCCE,
8784
+ AllocType))
8785
+ return false;
8775
8786
} else if (Init) {
8776
8787
if (!EvaluateInPlace(*Val, Info, Result, Init))
8777
8788
return false;
@@ -9597,6 +9608,16 @@ static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This,
9597
9608
.VisitInitListExpr(ILE, AllocType);
9598
9609
}
9599
9610
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
+
9600
9621
// Return true iff the given array filler may depend on the element index.
9601
9622
static bool MaybeElementDependentArrayFiller(const Expr *FillerExpr) {
9602
9623
// For now, just whitelist non-class value-initialization and initialization
0 commit comments