forked from OSchip/llvm-project
PR47143: Don't crash while constant-evaluating value-initialization of
an array of unknown bound as the initializer of an array new expression.
This commit is contained in:
parent
fbfd831dda
commit
bd08e0cf1c
|
@ -8987,6 +8987,7 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
|
|||
const Expr *Init = E->getInitializer();
|
||||
const InitListExpr *ResizedArrayILE = nullptr;
|
||||
const CXXConstructExpr *ResizedArrayCCE = nullptr;
|
||||
bool ValueInit = false;
|
||||
|
||||
QualType AllocType = E->getAllocatedType();
|
||||
if (Optional<const Expr*> ArraySize = E->getArraySize()) {
|
||||
|
@ -9030,7 +9031,14 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
|
|||
// -- the new-initializer is a braced-init-list and the number of
|
||||
// array elements for which initializers are provided [...]
|
||||
// exceeds the number of elements to initialize
|
||||
if (Init && !isa<CXXConstructExpr>(Init)) {
|
||||
if (!Init) {
|
||||
// No initialization is performed.
|
||||
} else if (isa<CXXScalarValueInitExpr>(Init) ||
|
||||
isa<ImplicitValueInitExpr>(Init)) {
|
||||
ValueInit = true;
|
||||
} else if (auto *CCE = dyn_cast<CXXConstructExpr>(Init)) {
|
||||
ResizedArrayCCE = CCE;
|
||||
} else {
|
||||
auto *CAT = Info.Ctx.getAsConstantArrayType(Init->getType());
|
||||
assert(CAT && "unexpected type for array initializer");
|
||||
|
||||
|
@ -9053,8 +9061,6 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
|
|||
// special handling for this case when we initialize.
|
||||
if (InitBound != AllocBound)
|
||||
ResizedArrayILE = cast<InitListExpr>(Init);
|
||||
} else if (Init) {
|
||||
ResizedArrayCCE = cast<CXXConstructExpr>(Init);
|
||||
}
|
||||
|
||||
AllocType = Info.Ctx.getConstantArrayType(AllocType, ArrayBound, nullptr,
|
||||
|
@ -9115,7 +9121,11 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (ResizedArrayILE) {
|
||||
if (ValueInit) {
|
||||
ImplicitValueInitExpr VIE(AllocType);
|
||||
if (!EvaluateInPlace(*Val, Info, Result, &VIE))
|
||||
return false;
|
||||
} else if (ResizedArrayILE) {
|
||||
if (!EvaluateArrayNewInitList(Info, Result, *Val, ResizedArrayILE,
|
||||
AllocType))
|
||||
return false;
|
||||
|
|
|
@ -950,6 +950,20 @@ namespace dynamic_alloc {
|
|||
p = new ((std::align_val_t)n) char[n];
|
||||
p = new char(n);
|
||||
}
|
||||
|
||||
namespace PR47143 {
|
||||
constexpr char *f(int n) {
|
||||
return new char[n]();
|
||||
}
|
||||
const char *p = f(3);
|
||||
constexpr bool test() {
|
||||
char *p = f(3);
|
||||
bool result = !p[0] && !p[1] && !p[2];
|
||||
delete [] p;
|
||||
return result;
|
||||
}
|
||||
static_assert(test());
|
||||
}
|
||||
}
|
||||
|
||||
struct placement_new_arg {};
|
||||
|
|
Loading…
Reference in New Issue