[llvm-branch-commits] [clang] ff47911 - PR47143: Don't crash while constant-evaluating value-initialization of
Richard Smith via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Aug 12 16:59:01 PDT 2020
Author: Richard Smith
Date: 2020-08-12T16:56:53-07:00
New Revision: ff47911ddfc10d023ef0debf229a60c9fce9443a
URL: https://github.com/llvm/llvm-project/commit/ff47911ddfc10d023ef0debf229a60c9fce9443a
DIFF: https://github.com/llvm/llvm-project/commit/ff47911ddfc10d023ef0debf229a60c9fce9443a.diff
LOG: PR47143: Don't crash while constant-evaluating value-initialization of
an array of unknown bound as the initializer of an array new expression.
(cherry picked from commit bd08e0cf1cb1f1f294e4253ba5907ec4c81b05fe)
Added:
Modified:
clang/lib/AST/ExprConstant.cpp
clang/test/SemaCXX/constant-expression-cxx2a.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 41a4ae4b91c8..8367ffc6f48c 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -8974,6 +8974,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()) {
@@ -9017,7 +9018,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");
@@ -9040,8 +9048,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,
@@ -9102,7 +9108,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;
diff --git a/clang/test/SemaCXX/constant-expression-cxx2a.cpp b/clang/test/SemaCXX/constant-expression-cxx2a.cpp
index f66f380b635f..344797bafb11 100644
--- a/clang/test/SemaCXX/constant-expression-cxx2a.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx2a.cpp
@@ -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 {};
More information about the llvm-branch-commits
mailing list