[clang] 3b150fb - [clang][bytecode] Handle negative array sizes in constexpr `new` instead of asserting (#155737)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 29 05:28:44 PDT 2025
Author: Samarth Narang
Date: 2025-08-29T08:28:40-04:00
New Revision: 3b150fb12839f6b34136a9a36369973adb89d634
URL: https://github.com/llvm/llvm-project/commit/3b150fb12839f6b34136a9a36369973adb89d634
DIFF: https://github.com/llvm/llvm-project/commit/3b150fb12839f6b34136a9a36369973adb89d634.diff
LOG: [clang][bytecode] Handle negative array sizes in constexpr `new` instead of asserting (#155737)
This patch fixes a crash in the constexpr interpreter when evaluating
`new T[n]` with a negative element count.
Fixes https://github.com/llvm/llvm-project/issues/152904
Added:
Modified:
clang/lib/AST/ByteCode/Interp.h
clang/test/AST/ByteCode/new-delete.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 92e60b6b88e6a..2da220237803e 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -3490,7 +3490,15 @@ inline bool AllocN(InterpState &S, CodePtr OpPC, PrimType T, const Expr *Source,
S.Stk.push<Pointer>(0, nullptr);
return true;
}
- assert(NumElements.isPositive());
+ if (NumElements.isNegative()) {
+ if (!IsNoThrow) {
+ S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_new_negative)
+ << NumElements.toDiagnosticString(S.getASTContext());
+ return false;
+ }
+ S.Stk.push<Pointer>(0, nullptr);
+ return true;
+ }
if (!CheckArraySize(S, OpPC, static_cast<uint64_t>(NumElements)))
return false;
diff --git a/clang/test/AST/ByteCode/new-delete.cpp b/clang/test/AST/ByteCode/new-delete.cpp
index 3f0e928c7664e..af747d7a15b12 100644
--- a/clang/test/AST/ByteCode/new-delete.cpp
+++ b/clang/test/AST/ByteCode/new-delete.cpp
@@ -1069,6 +1069,28 @@ namespace BaseCompare {
static_assert(foo());
}
+
+namespace NegativeArraySize {
+ constexpr void f() { // both-error {{constexpr function never produces a constant expression}}
+ int x = -1;
+ int *p = new int[x]; //both-note {{cannot allocate array; evaluated array bound -1 is negative}}
+ }
+} // namespace NegativeArraySize
+
+namespace NewNegSizeNothrow {
+ constexpr int get_neg_size() {
+ return -1;
+ }
+
+ constexpr bool test_nothrow_neg_size() {
+ int x = get_neg_size();
+ int* p = new (std::nothrow) int[x];
+ return p == nullptr;
+ }
+
+ static_assert(test_nothrow_neg_size(), "expected nullptr");
+} // namespace NewNegSizeNothrow
+
#else
/// Make sure we reject this prior to C++20
constexpr int a() { // both-error {{never produces a constant expression}}
More information about the cfe-commits
mailing list