[clang] [Clang] Add missing release note entry in GH226753 (PR #227078)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 28 18:00:58 PDT 2026
https://github.com/aokblast updated https://github.com/llvm/llvm-project/pull/227078
>From 75089644e3e92b140896710239f090e6f1e78c1e Mon Sep 17 00:00:00 2001
From: ShengYi Hung <aokblast at FreeBSD.org>
Date: Sun, 27 Sep 2026 23:36:18 -0500
Subject: [PATCH 1/2] [Clang] Add missing release note entry in GH226753
---
clang/docs/ReleaseNotes.md | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 3c6acf353f93f..f75e57f58b932 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -763,6 +763,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. (#GH226753)
+
#### Bug Fixes to AST Handling
- Fixed a non-deterministic ordering of unused local typedefs that made
>From 14a00a9c6da283f6d707e96c7a1dff094de96a13 Mon Sep 17 00:00:00 2001
From: ShengYi Hung <aokblast at FreeBSD.org>
Date: Mon, 28 Sep 2026 20:00:41 -0500
Subject: [PATCH 2/2] fixup! [Clang] Add missing release note entry in GH226753
---
clang/docs/ReleaseNotes.md | 2 +-
clang/test/AST/ByteCode/new-delete.cpp | 17 ++++++++++++
clang/test/SemaCXX/new-nothrow-by-value.cpp | 29 ---------------------
3 files changed, 18 insertions(+), 30 deletions(-)
delete mode 100644 clang/test/SemaCXX/new-nothrow-by-value.cpp
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index f75e57f58b932..3df4981e10a9f 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -766,7 +766,7 @@ features cannot lower the translation-unit ABI level;
- 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. (#GH226753)
+ it does not select a replaceable global allocation function. (#GH212211)
#### Bug Fixes to AST Handling
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()'}}
More information about the cfe-commits
mailing list