@@ -8677,6 +8677,10 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
8677
8677
static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This,
8678
8678
APValue &Result, const InitListExpr *ILE,
8679
8679
QualType AllocType);
8680
+ static bool EvaluateArrayNewConstructExpr(EvalInfo &Info, LValue &This,
8681
+ APValue &Result,
8682
+ const CXXConstructExpr *CCE,
8683
+ QualType AllocType);
8680
8684
8681
8685
bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
8682
8686
if (!Info.getLangOpts().CPlusPlus2a)
@@ -8726,6 +8730,7 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
8726
8730
8727
8731
const Expr *Init = E->getInitializer();
8728
8732
const InitListExpr *ResizedArrayILE = nullptr;
8733
+ const CXXConstructExpr *ResizedArrayCCE = nullptr;
8729
8734
8730
8735
QualType AllocType = E->getAllocatedType();
8731
8736
if (Optional<const Expr*> ArraySize = E->getArraySize()) {
@@ -8769,7 +8774,7 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
8769
8774
// -- the new-initializer is a braced-init-list and the number of
8770
8775
// array elements for which initializers are provided [...]
8771
8776
// exceeds the number of elements to initialize
8772
- if (Init) {
8777
+ if (Init && !isa<CXXConstructExpr>(Init) ) {
8773
8778
auto *CAT = Info.Ctx.getAsConstantArrayType(Init->getType());
8774
8779
assert(CAT && "unexpected type for array initializer");
8775
8780
@@ -8792,6 +8797,8 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
8792
8797
// special handling for this case when we initialize.
8793
8798
if (InitBound != AllocBound)
8794
8799
ResizedArrayILE = cast<InitListExpr>(Init);
8800
+ } else if (Init) {
8801
+ ResizedArrayCCE = cast<CXXConstructExpr>(Init);
8795
8802
}
8796
8803
8797
8804
AllocType = Info.Ctx.getConstantArrayType(AllocType, ArrayBound, nullptr,
@@ -8856,6 +8863,10 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
8856
8863
if (!EvaluateArrayNewInitList(Info, Result, *Val, ResizedArrayILE,
8857
8864
AllocType))
8858
8865
return false;
8866
+ } else if (ResizedArrayCCE) {
8867
+ if (!EvaluateArrayNewConstructExpr(Info, Result, *Val, ResizedArrayCCE,
8868
+ AllocType))
8869
+ return false;
8859
8870
} else if (Init) {
8860
8871
if (!EvaluateInPlace(*Val, Info, Result, Init))
8861
8872
return false;
@@ -9683,6 +9694,16 @@ static bool EvaluateArrayNewInitList(EvalInfo &Info, LValue &This,
9683
9694
.VisitInitListExpr(ILE, AllocType);
9684
9695
}
9685
9696
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
+
9686
9707
// Return true iff the given array filler may depend on the element index.
9687
9708
static bool MaybeElementDependentArrayFiller(const Expr *FillerExpr) {
9688
9709
// For now, just whitelist non-class value-initialization and initialization
0 commit comments