Author: DaanishD20
Date: 2026-07-07T08:55:48Z
New Revision: 81e317971d50396fc68a602a505eb85572c51373

URL: 
https://github.com/llvm/llvm-project/commit/81e317971d50396fc68a602a505eb85572c51373
DIFF: 
https://github.com/llvm/llvm-project/commit/81e317971d50396fc68a602a505eb85572c51373.diff

LOG: [clang] Fix constant-evaluator crash on array new with no size (#207730)

An array new-expression whose bound is neither specified nor deducible
from its initializer (for example `new int[]()`) is ill-formed and is
already diagnosed by Sema with `error: cannot determine allocated array
size from initializer`. However, the constant evaluator still tried to
evaluate the recovery expression. In
`PointerExprEvaluator::VisitCXXNewExpr`
the array size is unavailable (`E->getArraySize()` is `nullopt`), so the
allocation fell through to the scalar-new path, producing an array
`APValue` stored under a scalar type. Reading that object later asserted
in `Type::castAsArrayTypeUnsafe()` (`isa<ArrayType>(CanonicalType)`)
from
`CheckEvaluationResult`.

This patch detects an array new-expression whose size could not be
determined and bails out of constant evaluation.

Fixes #200139

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.md
    clang/lib/AST/ExprConstant.cpp
    clang/test/SemaCXX/constant-expression-cxx2a.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index a37e1be5862b3..cc85604343da9 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -773,6 +773,7 @@ latest release, please see the [Clang Web 
Site](https://clang.llvm.org) or the
 - Fixed an assertion where we improperly handled implicit conversions to 
integral types from an atomic-type with a conversion function. (#GH201770)
 - Fixed assertion failures involving code completion with delayed default 
arguments and exception specifications. (#GH200879)
 - Fixed a regression where calling a function that takes a class-type 
parameter by value inside `decltype` of a concept could be incorrectly rejected 
when used as a non-type template argument. (#GH175831)
+- Fixed a crash in the constant evaluator when an ill-formed array 
new-expression whose bound could not be determined (e.g. `new int[]()`) was 
used in a constant expression. (#GH200139)
 
 #### Bug Fixes to Compiler Builtins
 

diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 109dc627133f2..28772a574e60a 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -10913,6 +10913,13 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const 
CXXNewExpr *E) {
 
     AllocType = Info.Ctx.getConstantArrayType(AllocType, ArrayBound, nullptr,
                                               ArraySizeModifier::Normal, 0);
+  } else if (E->isArray()) {
+    // We have an array new-expression whose array size could not be
+    // determined, e.g. 'new int[]()', where the bound is neither given nor
+    // deducible from the initializer. This is ill-formed and already
+    // diagnosed, so bail out rather than mis-evaluating a scalar allocation
+    // as an array (which would later crash the evaluator).
+    return false;
   } else {
     assert(!AllocType->isArrayType() &&
            "array allocation with non-array new");

diff  --git a/clang/test/SemaCXX/constant-expression-cxx2a.cpp 
b/clang/test/SemaCXX/constant-expression-cxx2a.cpp
index 396a8df21a3e3..94ecafc081302 100644
--- a/clang/test/SemaCXX/constant-expression-cxx2a.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx2a.cpp
@@ -898,6 +898,12 @@ namespace dynamic_alloc {
   static_assert(erroneous_array_bound(-1)); // expected-error {{constant 
expression}} expected-note {{in call}}
   static_assert(erroneous_array_bound(1LL << 62)); // expected-error 
{{constant expression}} expected-note {{in call}}
 
+  // An array new-expression whose bound is neither given nor deducible from 
the
+  // initializer is ill-formed; the constant evaluator must reject it 
gracefully
+  // rather than crash. See GH200139.
+  static_assert((new int[]())[0] == 0); // expected-error {{cannot determine 
allocated array size from initializer}} \
+                                        // expected-error {{static assertion 
expression is not an integral constant expression}}
+
   constexpr bool erroneous_array_bound_nothrow(long long n) {
     int *p = new (std::nothrow) int[n];
     bool result = p != 0;


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to