[libcxx-commits] [libcxx] [libc++] P2747R2: `constexpr` placement new (library part) (PR #105768)

via libcxx-commits libcxx-commits at lists.llvm.org
Thu Aug 22 19:09:14 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: A. Jiang (frederick-vs-ja)

<details>
<summary>Changes</summary>

Paper link: https://wg21.link/P2747R2

The library changes affect direct `operator new` and `operator new[]` calls even when the core language changes are absent. "Actual" placement new tests are not added yet as the core language changes haven't been implemented (pending on #<!-- -->97957).

Drive-by: Formatting the whole `new.pass.cpp` and `new_array.pass.cpp`.

Closes #<!-- -->105427.

---
Full diff: https://github.com/llvm/llvm-project/pull/105768.diff


12 Files Affected:

- (modified) libcxx/docs/FeatureTestMacroTable.rst (+1-1) 
- (modified) libcxx/docs/ReleaseNotes/20.rst (+1-1) 
- (modified) libcxx/docs/Status/Cxx2cPapers.csv (+1-1) 
- (modified) libcxx/include/__config (+6) 
- (modified) libcxx/include/new (+8-2) 
- (modified) libcxx/include/version (+1-1) 
- (modified) libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.placement/new.pass.cpp (+21-10) 
- (modified) libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.placement/new_array.pass.cpp (+25-14) 
- (modified) libcxx/test/std/language.support/support.limits/support.limits.general/new.version.compile.pass.cpp (+5-11) 
- (modified) libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp (+5-11) 
- (modified) libcxx/test/support/test_macros.h (+6) 
- (modified) libcxx/utils/generate_feature_test_macro_components.py (-1) 


``````````diff
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index a1506e115fe70f..8a429ddd476010 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -404,7 +404,7 @@ Status
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_bitset``                                       ``202306L``
     ---------------------------------------------------------- -----------------
-    ``__cpp_lib_constexpr_new``                                *unimplemented*
+    ``__cpp_lib_constexpr_new``                                ``202406L``
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_constrained_equality``                         *unimplemented*
     ---------------------------------------------------------- -----------------
diff --git a/libcxx/docs/ReleaseNotes/20.rst b/libcxx/docs/ReleaseNotes/20.rst
index fe9f4c1973cdb4..d048ab32d1f130 100644
--- a/libcxx/docs/ReleaseNotes/20.rst
+++ b/libcxx/docs/ReleaseNotes/20.rst
@@ -38,7 +38,7 @@ What's New in Libc++ 20.0.0?
 Implemented Papers
 ------------------
 
-- TODO
+- P2747R2 - ``constexpr`` placement new
 
 
 Improvements and New Features
diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index dd62bcc2555ffc..bfb5e34da458d4 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -63,7 +63,7 @@
 "`P2642R6 <https://wg21.link/P2642R6>`__","Padded ``mdspan`` layouts","2024-03 (Tokyo)","","",""
 "`P3029R1 <https://wg21.link/P3029R1>`__","Better ``mdspan``'s CTAD","2024-03 (Tokyo)","|Complete|","19.0",""
 "","","","","",""
-"`P2747R2 <https://wg21.link/P2747R2>`__","``constexpr`` placement new","2024-06 (St. Louis)","","",""
+"`P2747R2 <https://wg21.link/P2747R2>`__","``constexpr`` placement new","2024-06 (St. Louis)","|Complete|","20.0",""
 "`P2997R1 <https://wg21.link/P2997R1>`__","Removing the common reference requirement from the indirectly invocable concepts","2024-06 (St. Louis)","|Complete| [#note-P2997R1]_","19.0",""
 "`P2389R2 <https://wg21.link/P2389R2>`__","``dextents`` Index Type Parameter","2024-06 (St. Louis)","|Complete|","19.0",""
 "`P3168R2 <https://wg21.link/P3168R2>`__","Give ``std::optional`` Range Support","2024-06 (St. Louis)","","","|ranges|"
diff --git a/libcxx/include/__config b/libcxx/include/__config
index 392053a64a8dc1..9dd8d46b48d28f 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -788,6 +788,12 @@ typedef __char32_t char32_t;
 #    define _LIBCPP_CONSTEXPR_SINCE_CXX23
 #  endif
 
+#  if _LIBCPP_STD_VER >= 26
+#    define _LIBCPP_CONSTEXPR_SINCE_CXX26 constexpr
+#  else
+#    define _LIBCPP_CONSTEXPR_SINCE_CXX26
+#  endif
+
 #  ifndef _LIBCPP_WEAK
 #    define _LIBCPP_WEAK __attribute__((__weak__))
 #  endif
diff --git a/libcxx/include/new b/libcxx/include/new
index 214dbc398530bb..dc48cf44a3e7a2 100644
--- a/libcxx/include/new
+++ b/libcxx/include/new
@@ -242,8 +242,14 @@ _LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::size_t __sz,
 #    endif
 #  endif
 
-_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI void* operator new(std::size_t, void* __p) _NOEXCEPT { return __p; }
-_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI void* operator new[](std::size_t, void* __p) _NOEXCEPT { return __p; }
+_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void*
+operator new(std::size_t, void* __p) _NOEXCEPT {
+  return __p;
+}
+_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX26 void*
+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 {}
 
diff --git a/libcxx/include/version b/libcxx/include/version
index fe64343eafbc9c..aeddda625fc960 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -510,7 +510,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # undef  __cpp_lib_bind_front
 # define __cpp_lib_bind_front                           202306L
 # define __cpp_lib_bitset                               202306L
-// # define __cpp_lib_constexpr_new                        202406L
+# define __cpp_lib_constexpr_new                        202406L
 // # define __cpp_lib_constrained_equality                 202403L
 // # define __cpp_lib_copyable_function                    202306L
 // # define __cpp_lib_debugging                            202311L
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 b857b397fc83e4..3e48a3634533a5 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
@@ -15,19 +15,30 @@
 
 int A_constructed = 0;
 
-struct A
-{
-    A() {++A_constructed;}
-    ~A() {--A_constructed;}
+struct A {
+  A() { ++A_constructed; }
+  ~A() { --A_constructed; }
 };
 
-int main(int, char**)
-{
-    char buf[sizeof(A)];
+TEST_CONSTEXPR_CXX26 void test_direct_call() {
+  assert(::operator new(sizeof(int), &A_constructed) == &A_constructed);
 
-    A* ap = new(buf) A;
-    assert((char*)ap == buf);
-    assert(A_constructed == 1);
+  char ch = '*';
+  assert(::operator new(1, &ch) == &ch);
+  assert(ch == '*');
+}
+
+#if TEST_STD_VER >= 26
+static_assert((test_direct_call(), true));
+#endif
+
+int main(int, char**) {
+  char buf[sizeof(A)];
+
+  A* ap = new (buf) A;
+  assert((char*)ap == buf);
+  assert(A_constructed == 1);
 
+  test_direct_call();
   return 0;
 }
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 99a5442b6fb1f8..d318e338185c7e 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
@@ -15,23 +15,34 @@
 
 int A_constructed = 0;
 
-struct A
-{
-    A() {++A_constructed;}
-    ~A() {--A_constructed;}
+struct A {
+  A() { ++A_constructed; }
+  ~A() { --A_constructed; }
 };
 
-int main(int, char**)
-{
-    const std::size_t Size = 3;
-    // placement new might require additional space.
-    const std::size_t ExtraSize = 64;
-    char buf[Size*sizeof(A) + ExtraSize];
+TEST_CONSTEXPR_CXX26 void test_direct_call() {
+  assert(::operator new[](sizeof(int), &A_constructed) == &A_constructed);
 
-    A* ap = new(buf) A[Size];
-    assert((char*)ap >= buf);
-    assert((char*)ap < (buf + ExtraSize));
-    assert(A_constructed == Size);
+  char ch = '*';
+  assert(::operator new[](1, &ch) == &ch);
+  assert(ch == '*');
+}
+
+#if TEST_STD_VER >= 26
+static_assert((test_direct_call(), true));
+#endif
+
+int main(int, char**) {
+  const std::size_t Size = 3;
+  // placement new might require additional space.
+  const std::size_t ExtraSize = 64;
+  char buf[Size * sizeof(A) + ExtraSize];
+
+  A* ap = new (buf) A[Size];
+  assert((char*)ap >= buf);
+  assert((char*)ap < (buf + ExtraSize));
+  assert(A_constructed == Size);
 
+  test_direct_call();
   return 0;
 }
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/new.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/new.version.compile.pass.cpp
index 17c1bd71eee675..e6308ae36085ca 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/new.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/new.version.compile.pass.cpp
@@ -171,17 +171,11 @@
 
 #elif TEST_STD_VER > 23
 
-# if !defined(_LIBCPP_VERSION)
-#   ifndef __cpp_lib_constexpr_new
-#     error "__cpp_lib_constexpr_new should be defined in c++26"
-#   endif
-#   if __cpp_lib_constexpr_new != 202406L
-#     error "__cpp_lib_constexpr_new should have the value 202406L in c++26"
-#   endif
-# else // _LIBCPP_VERSION
-#   ifdef __cpp_lib_constexpr_new
-#     error "__cpp_lib_constexpr_new should not be defined because it is unimplemented in libc++!"
-#   endif
+# ifndef __cpp_lib_constexpr_new
+#   error "__cpp_lib_constexpr_new should be defined in c++26"
+# endif
+# if __cpp_lib_constexpr_new != 202406L
+#   error "__cpp_lib_constexpr_new should have the value 202406L in c++26"
 # endif
 
 # if TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index b8bad696f1bae0..4ddd35ddff23f1 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -6554,17 +6554,11 @@
 #   error "__cpp_lib_constexpr_memory should have the value 202202L in c++26"
 # endif
 
-# if !defined(_LIBCPP_VERSION)
-#   ifndef __cpp_lib_constexpr_new
-#     error "__cpp_lib_constexpr_new should be defined in c++26"
-#   endif
-#   if __cpp_lib_constexpr_new != 202406L
-#     error "__cpp_lib_constexpr_new should have the value 202406L in c++26"
-#   endif
-# else // _LIBCPP_VERSION
-#   ifdef __cpp_lib_constexpr_new
-#     error "__cpp_lib_constexpr_new should not be defined because it is unimplemented in libc++!"
-#   endif
+# ifndef __cpp_lib_constexpr_new
+#   error "__cpp_lib_constexpr_new should be defined in c++26"
+# endif
+# if __cpp_lib_constexpr_new != 202406L
+#   error "__cpp_lib_constexpr_new should have the value 202406L in c++26"
 # endif
 
 # ifndef __cpp_lib_constexpr_numeric
diff --git a/libcxx/test/support/test_macros.h b/libcxx/test/support/test_macros.h
index e96208c85d1d24..b52baaeaf139a9 100644
--- a/libcxx/test/support/test_macros.h
+++ b/libcxx/test/support/test_macros.h
@@ -184,6 +184,12 @@
 #  define TEST_CONSTEXPR_CXX23
 #endif
 
+#if TEST_STD_VER >= 26
+#  define TEST_CONSTEXPR_CXX26 constexpr
+#else
+#  define TEST_CONSTEXPR_CXX26
+#endif
+
 #define TEST_ALIGNAS_TYPE(...) TEST_ALIGNAS(TEST_ALIGNOF(__VA_ARGS__))
 
 #if !TEST_HAS_FEATURE(cxx_rtti) && !defined(__cpp_rtti) \
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index b041b08f02aac5..a4404380851578 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -363,7 +363,6 @@ def add_version_header(tc):
             "name": "__cpp_lib_constexpr_new",
             "values": {"c++26": 202406},  # P2747R2 constexpr placement new
             "headers": ["new"],
-            "unimplemented": True,
         },
         {
             "name": "__cpp_lib_constexpr_numeric",

``````````

</details>


https://github.com/llvm/llvm-project/pull/105768


More information about the libcxx-commits mailing list