Author: aokblast Date: 2026-09-29T02:14:21Z New Revision: 31d7b51dbd5a8a5e58631a3c77421209f562ea5c
URL: https://github.com/llvm/llvm-project/commit/31d7b51dbd5a8a5e58631a3c77421209f562ea5c DIFF: https://github.com/llvm/llvm-project/commit/31d7b51dbd5a8a5e58631a3c77421209f562ea5c.diff LOG: [Clang] Add missing release note entry in #226753 (#227078) As per the feedback from #226753, we add release note for GH-212211. Also move the test to new-delete.cpp. Assisted-by: Claude Added: Modified: clang/docs/ReleaseNotes.md clang/test/AST/ByteCode/new-delete.cpp Removed: clang/test/SemaCXX/new-nothrow-by-value.cpp ################################################################################ diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index b71758e4b9647..49d669db5749c 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -767,6 +767,11 @@ features cannot lower the translation-unit ABI level; lookup before asserting that the name is not dependent, avoiding an assertion after an earlier diagnostic has caused the declaration to be unavailable. (#GH220525) +- Fixed a crash in constant evaluation when a new-expression selects a + user-declared allocation function that takes std::nothrow_t by value. Such + a new-expression is now correctly rejected in a constant expression because + it does not select a replaceable global allocation function. (#GH212211) + #### Bug Fixes to AST Handling - Fixed a non-deterministic ordering of unused local typedefs that made diff --git a/clang/test/AST/ByteCode/new-delete.cpp b/clang/test/AST/ByteCode/new-delete.cpp index 24195d77962b8..e5ddd8eb2a037 100644 --- a/clang/test/AST/ByteCode/new-delete.cpp +++ b/clang/test/AST/ByteCode/new-delete.cpp @@ -343,6 +343,18 @@ namespace placement_new_delete { void operator delete(DestroyingDelete*, std::destroying_delete_t); }; struct alignas(64) Overaligned {}; + struct NothrowByValue { + void *operator new(std::size_t, std::nothrow_t) noexcept; + void *operator new[](std::size_t, std::nothrow_t) noexcept; + }; + + // Constant-folding the new-expression used to assume the (std::nothrow) + // placement argument was an lvalue and assert on the prvalue produced when a + // user-declared allocation function takes std::nothrow_t by value. + void nothrow_by_value_fold(NothrowByValue *p) { + p = (1 ? new (std::nothrow) NothrowByValue[1] : nullptr); + p = (1 ? new (std::nothrow) NothrowByValue : nullptr); + } constexpr bool ok() { delete new Overaligned; @@ -376,6 +388,10 @@ namespace placement_new_delete { // unreasonable to expect implementations to support this. delete new (std::align_val_t{64}) Overaligned; // both-note {{this placement new expression is not supported in constant expressions}} break; + + case 5: + delete new (std::nothrow) NothrowByValue; // both-note {{call to class-specific 'operator new'}} + break; } return true; @@ -387,6 +403,7 @@ namespace placement_new_delete { static_assert(bad(3)); // both-error {{constant expression}} both-note {{in call}} static_assert(bad(4)); // both-error {{constant expression}} \ // both-note {{in call}} + static_assert(bad(5)); // both-error {{constant expression}} both-note {{in call}} } diff --git a/clang/test/SemaCXX/new-nothrow-by-value.cpp b/clang/test/SemaCXX/new-nothrow-by-value.cpp deleted file mode 100644 index c2985ad582219..0000000000000 --- a/clang/test/SemaCXX/new-nothrow-by-value.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s -// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s -fexperimental-new-constant-interpreter - -// [expr.const] only permits a new-expression in a constant expression when it -// selects a replaceable global allocation function. None of them take -// std::nothrow_t by value, so a user-declared allocation function that does -// must be rejected before examining its placement argument. The constant -// evaluator used to assume the argument was always an lvalue and crashed on -// the prvalue produced here. - -namespace std { -inline constexpr struct nothrow_t { -} nothrow; -} // namespace std - -void *operator new[](__SIZE_TYPE__, std::nothrow_t) noexcept; -void *operator new(__SIZE_TYPE__, std::nothrow_t) noexcept; - -void set(int *p) { - p = (1 ? new (std::nothrow) int[1] : nullptr); - p = (1 ? new (std::nothrow) int : nullptr); -} - -constexpr bool by_value() { // expected-error {{constexpr function never produces a constant expression}} - int *p = new (std::nothrow) int; // expected-note 2{{call to placement 'operator new'}} - delete p; - return true; -} -static_assert(by_value()); // expected-error {{not an integral constant expression}} expected-note {{in call to 'by_value()'}} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
