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}} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
