Skip to content

Commit bd08e0c

Browse files
committed
PR47143: Don't crash while constant-evaluating value-initialization of
an array of unknown bound as the initializer of an array new expression.
1 parent fbfd831 commit bd08e0c

File tree

2 files changed

+28
-4
lines changed

2 files changed

+28
-4
lines changed

clang/lib/AST/ExprConstant.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8987,6 +8987,7 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
89878987
const Expr *Init = E->getInitializer();
89888988
const InitListExpr *ResizedArrayILE = nullptr;
89898989
const CXXConstructExpr *ResizedArrayCCE = nullptr;
8990+
bool ValueInit = false;
89908991

89918992
QualType AllocType = E->getAllocatedType();
89928993
if (Optional<const Expr*> ArraySize = E->getArraySize()) {
@@ -9030,7 +9031,14 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
90309031
// -- the new-initializer is a braced-init-list and the number of
90319032
// array elements for which initializers are provided [...]
90329033
// exceeds the number of elements to initialize
9033-
if (Init && !isa<CXXConstructExpr>(Init)) {
9034+
if (!Init) {
9035+
// No initialization is performed.
9036+
} else if (isa<CXXScalarValueInitExpr>(Init) ||
9037+
isa<ImplicitValueInitExpr>(Init)) {
9038+
ValueInit = true;
9039+
} else if (auto *CCE = dyn_cast<CXXConstructExpr>(Init)) {
9040+
ResizedArrayCCE = CCE;
9041+
} else {
90349042
auto *CAT = Info.Ctx.getAsConstantArrayType(Init->getType());
90359043
assert(CAT && "unexpected type for array initializer");
90369044

@@ -9053,8 +9061,6 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
90539061
// special handling for this case when we initialize.
90549062
if (InitBound != AllocBound)
90559063
ResizedArrayILE = cast<InitListExpr>(Init);
9056-
} else if (Init) {
9057-
ResizedArrayCCE = cast<CXXConstructExpr>(Init);
90589064
}
90599065

90609066
AllocType = Info.Ctx.getConstantArrayType(AllocType, ArrayBound, nullptr,
@@ -9115,7 +9121,11 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
91159121
return false;
91169122
}
91179123

9118-
if (ResizedArrayILE) {
9124+
if (ValueInit) {
9125+
ImplicitValueInitExpr VIE(AllocType);
9126+
if (!EvaluateInPlace(*Val, Info, Result, &VIE))
9127+
return false;
9128+
} else if (ResizedArrayILE) {
91199129
if (!EvaluateArrayNewInitList(Info, Result, *Val, ResizedArrayILE,
91209130
AllocType))
91219131
return false;

clang/test/SemaCXX/constant-expression-cxx2a.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -950,6 +950,20 @@ namespace dynamic_alloc {
950950
p = new ((std::align_val_t)n) char[n];
951951
p = new char(n);
952952
}
953+
954+
namespace PR47143 {
955+
constexpr char *f(int n) {
956+
return new char[n]();
957+
}
958+
const char *p = f(3);
959+
constexpr bool test() {
960+
char *p = f(3);
961+
bool result = !p[0] && !p[1] && !p[2];
962+
delete [] p;
963+
return result;
964+
}
965+
static_assert(test());
966+
}
953967
}
954968

955969
struct placement_new_arg {};

0 commit comments

Comments
 (0)