Author: Richard Smith Date: 2020-08-12T16:53:45-07:00 New Revision: bd08e0cf1cb1f1f294e4253ba5907ec4c81b05fe
URL: https://github.com/llvm/llvm-project/commit/bd08e0cf1cb1f1f294e4253ba5907ec4c81b05fe DIFF: https://github.com/llvm/llvm-project/commit/bd08e0cf1cb1f1f294e4253ba5907ec4c81b05fe.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. 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 4238adb5a947..448a683c9088 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -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; 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 {}; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits