https://github.com/snarang181 updated https://github.com/llvm/llvm-project/pull/155737
>From 0b13b0e77e184666d46450b264e1237e6c41a1de Mon Sep 17 00:00:00 2001 From: Samarth Narang <snar...@umass.edu> Date: Wed, 27 Aug 2025 22:45:25 -0400 Subject: [PATCH 1/2] Enable nullptr handle with negative elemsize in a dynamic allocation --- clang/lib/AST/ByteCode/Interp.h | 7 ++++++- clang/test/SemaCXX/new-neg-size.cpp | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 clang/test/SemaCXX/new-neg-size.cpp diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index 92e60b6b88e6a..e505712b60dd3 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -3490,7 +3490,12 @@ 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.isPositive()) { + if (!IsNoThrow) + 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/SemaCXX/new-neg-size.cpp b/clang/test/SemaCXX/new-neg-size.cpp new file mode 100644 index 0000000000000..4b5a0d4bfe228 --- /dev/null +++ b/clang/test/SemaCXX/new-neg-size.cpp @@ -0,0 +1,15 @@ +// RUN: not %clang_cc1 -std=c++20 -fsyntax-only %s 2>&1 \ +// RUN: | FileCheck %s --implicit-check-not='Assertion `NumElements.isPositive()` failed' + +// In C++20, constexpr dynamic allocation is permitted *only* if valid. +// A negative element count must be diagnosed (and must not crash). + +constexpr void f_bad_neg() { + int a = -1; + (void) new int[a]; // triggers negative-size path in the interpreter +} + +// Force evaluation so we definitely run the constexpr interpreter. +constexpr bool force_eval = (f_bad_neg(), true); + +// CHECK: error: constexpr function never produces a constant expression >From 6d28107ebb963803b3bf6c4ae09734ec1ec6b526 Mon Sep 17 00:00:00 2001 From: Samarth Narang <snar...@umass.edu> Date: Wed, 27 Aug 2025 23:10:05 -0400 Subject: [PATCH 2/2] Add test case --- clang/test/SemaCXX/new-neg-size.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/clang/test/SemaCXX/new-neg-size.cpp b/clang/test/SemaCXX/new-neg-size.cpp index 4b5a0d4bfe228..e03f34c183809 100644 --- a/clang/test/SemaCXX/new-neg-size.cpp +++ b/clang/test/SemaCXX/new-neg-size.cpp @@ -1,7 +1,7 @@ // RUN: not %clang_cc1 -std=c++20 -fsyntax-only %s 2>&1 \ // RUN: | FileCheck %s --implicit-check-not='Assertion `NumElements.isPositive()` failed' -// In C++20, constexpr dynamic allocation is permitted *only* if valid. +// In C++20, constexpr dynamic allocation is permitted only if valid. // A negative element count must be diagnosed (and must not crash). constexpr void f_bad_neg() { @@ -9,7 +9,17 @@ constexpr void f_bad_neg() { (void) new int[a]; // triggers negative-size path in the interpreter } -// Force evaluation so we definitely run the constexpr interpreter. -constexpr bool force_eval = (f_bad_neg(), true); +struct __nothrow_t { }; +extern const __nothrow_t __nothrow_dummy; +void* operator new[](unsigned long, const __nothrow_t&) noexcept; -// CHECK: error: constexpr function never produces a constant expression +// Ensure we take the nothrow overload. +constexpr void f_bad_neg_nothrow() { + (void) new (__nothrow_dummy) int[-7]; // should evaluate to nullptr (no crash) +} + +// Force evaluation so the constexpr interpreter actually runs both cases. +constexpr bool force_eval1 = (f_bad_neg(), true); +constexpr bool force_eval2 = (f_bad_neg_nothrow(), true); + +// CHECK: error: constexpr function {{(never produces|is not a)}} constant expression \ No newline at end of file _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits