[libcxx-commits] [libcxx] 7cb66a4 - [libc++] Implement LWG4477: placement operator delete should be constexpr (#189915)
via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Apr 8 06:48:38 PDT 2026
Author: Fernando Pelliccioni
Date: 2026-04-08T21:48:32+08:00
New Revision: 7cb66a448ace7ae2acd84e7e9bec73cfc560efe0
URL: https://github.com/llvm/llvm-project/commit/7cb66a448ace7ae2acd84e7e9bec73cfc560efe0
DIFF: https://github.com/llvm/llvm-project/commit/7cb66a448ace7ae2acd84e7e9bec73cfc560efe0.diff
LOG: [libc++] Implement LWG4477: placement operator delete should be constexpr (#189915)
Implement the proposed resolution of
[LWG4477](https://cplusplus.github.io/LWG/issue4477).
P2747R2 made placement `operator new` constexpr since C++26, but the
corresponding placement `operator delete` was not. When a constructor
throws during placement new in a constant expression, the placement
delete is invoked and fails because it's not constexpr.
Add `_LIBCPP_CONSTEXPR_SINCE_CXX26` to placement `operator delete(void*,
void*)` and `operator delete[](void*, void*)`.
Closes #189843
Added:
Modified:
libcxx/docs/Status/Cxx2cIssues.csv
libcxx/include/__new/placement_new_delete.h
libcxx/include/new
libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.placement/new.pass.cpp
libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.placement/new_array.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/docs/Status/Cxx2cIssues.csv b/libcxx/docs/Status/Cxx2cIssues.csv
index 75972e0b2874c..6f5af8eb9dbee 100644
--- a/libcxx/docs/Status/Cxx2cIssues.csv
+++ b/libcxx/docs/Status/Cxx2cIssues.csv
@@ -298,7 +298,7 @@
"`LWG4472 <https://wg21.link/LWG4472>`__","``std::atomic_ref<const T>`` can be constructed from temporaries","2026-03 (Croydon)","","","`#189840 <https://github.com/llvm/llvm-project/issues/189840>`__",""
"`LWG4474 <https://wg21.link/LWG4474>`__","""`round_to_nearest`"" rounding mode is unclear","2026-03 (Croydon)","","","`#189841 <https://github.com/llvm/llvm-project/issues/189841>`__",""
"`LWG4476 <https://wg21.link/LWG4476>`__","``run_loop`` should not have a ``set_error`` completion","2026-03 (Croydon)","","","`#189842 <https://github.com/llvm/llvm-project/issues/189842>`__",""
-"`LWG4477 <https://wg21.link/LWG4477>`__","Placement ``operator delete`` should be constexpr","2026-03 (Croydon)","","","`#189843 <https://github.com/llvm/llvm-project/issues/189843>`__",""
+"`LWG4477 <https://wg21.link/LWG4477>`__","Placement ``operator delete`` should be constexpr","2026-03 (Croydon)","|Complete|","23","`#189843 <https://github.com/llvm/llvm-project/issues/189843>`__",""
"`LWG4478 <https://wg21.link/LWG4478>`__","``meta::has_identifier`` is not specified for annotations","2026-03 (Croydon)","","","`#189844 <https://github.com/llvm/llvm-project/issues/189844>`__",""
"`LWG4480 <https://wg21.link/LWG4480>`__","``<stdatomic.h>`` should provide ``ATOMIC_CHAR8_T_LOCK_FREE``","2026-03 (Croydon)","","","`#189845 <https://github.com/llvm/llvm-project/issues/189845>`__",""
"`LWG4481 <https://wg21.link/LWG4481>`__","Disallow ``chrono::duration<const T, P>``","2026-03 (Croydon)","","","`#189846 <https://github.com/llvm/llvm-project/issues/189846>`__",""
diff --git a/libcxx/include/__new/placement_new_delete.h b/libcxx/include/__new/placement_new_delete.h
index 42c9f34036775..74692f36fd04c 100644
--- a/libcxx/include/__new/placement_new_delete.h
+++ b/libcxx/include/__new/placement_new_delete.h
@@ -27,8 +27,8 @@ operator new(std::size_t, void* __p) _NOEXCEPT {
operator new[](std::size_t, void* __p) _NOEXCEPT {
return __p;
}
-inline _LIBCPP_HIDE_FROM_ABI void operator delete(void*, void*) _NOEXCEPT {}
-inline _LIBCPP_HIDE_FROM_ABI void operator delete[](void*, void*) _NOEXCEPT {}
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void operator delete(void*, void*) _NOEXCEPT {}
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void operator delete[](void*, void*) _NOEXCEPT {}
#endif
#endif // _LIBCPP___NEW_PLACEMENT_NEW_DELETE_H
diff --git a/libcxx/include/new b/libcxx/include/new
index 4d72ec27675c9..ef66c67ccfbcc 100644
--- a/libcxx/include/new
+++ b/libcxx/include/new
@@ -81,8 +81,8 @@ void operator delete[](void* ptr, std::align_val_t alignment,
void* operator new (std::size_t size, void* ptr) noexcept; // nodiscard in C++20, constexpr since C++26
void* operator new[](std::size_t size, void* ptr) noexcept; // nodiscard in C++20, constexpr since C++26
-void operator delete (void* ptr, void*) noexcept;
-void operator delete[](void* ptr, void*) noexcept;
+void operator delete (void* ptr, void*) noexcept; // constexpr since C++26
+void operator delete[](void* ptr, void*) noexcept; // constexpr since C++26
*/
diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.placement/new.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.placement/new.pass.cpp
index 55be3f72508da..8c4f06ad07bbe 100644
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.placement/new.pass.cpp
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.placement/new.pass.cpp
@@ -25,7 +25,10 @@ TEST_CONSTEXPR_OPERATOR_NEW void test_direct_call() {
char ch = '*';
assert(::operator new(1, &ch) == &ch);
+ ::operator delete(&ch, &ch);
assert(ch == '*');
+
+ ::operator delete(nullptr, nullptr);
}
#ifdef __cpp_lib_constexpr_new
diff --git a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.placement/new_array.pass.cpp b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.placement/new_array.pass.cpp
index 1f7b08ec641c3..675b0f65470e8 100644
--- a/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.placement/new_array.pass.cpp
+++ b/libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.placement/new_array.pass.cpp
@@ -26,7 +26,10 @@ TEST_CONSTEXPR_OPERATOR_NEW void test_direct_call() {
char ch = '*';
assert(::operator new[](1, &ch) == &ch);
+ ::operator delete[](&ch, &ch);
assert(ch == '*');
+
+ ::operator delete[](nullptr, nullptr);
}
#ifdef __cpp_lib_constexpr_new
More information about the libcxx-commits
mailing list