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 <[email protected]>
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 <[email protected]>
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()'}}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to