]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Implement proposed resolution of LWG4477 [PR122671]
authorJakub Jelinek <jakub@redhat.com>
Wed, 19 Nov 2025 08:38:17 +0000 (09:38 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 19 Nov 2025 08:38:17 +0000 (09:38 +0100)
This patch implements the proposed resolution of
https://cplusplus.github.io/LWG/issue4477
The PR complains that one can't successfully throw from constructor
in placement new in a constant expression and catch that exception
later on.  The problem is while P2747R2 made placement ::operator new
and ::operator new[] constexpr, when the ctor throws it invokes also
these weird placement ::operator delete and ::operator delete[]
which intentionally perform no action, and those weren't constexpr,
so constant expression evaluation failed.

2025-11-19  Jakub Jelinek  <jakub@redhat.com>

PR libstdc++/122671
* libsupc++/new (::operator delete, ::operator delete[]): Implement
proposed LWG4477 resolution.  Use _GLIBCXX_PLACEMENT_CONSTEXPR for
placement operator deletes.

* g++.dg/cpp26/constexpr-eh17.C: New test.

gcc/testsuite/g++.dg/cpp26/constexpr-eh17.C [new file with mode: 0644]
libstdc++-v3/libsupc++/new

diff --git a/gcc/testsuite/g++.dg/cpp26/constexpr-eh17.C b/gcc/testsuite/g++.dg/cpp26/constexpr-eh17.C
new file mode 100644 (file)
index 0000000..4d83d0d
--- /dev/null
@@ -0,0 +1,38 @@
+// PR libstdc++/122671
+// { dg-do compile { target c++26 } }
+
+#include <new>
+#include <memory>
+
+consteval auto
+foo ()
+{
+  struct E {};
+  struct O
+  {
+    constexpr explicit O (int x)
+    {
+      if (x < 0) { throw E {}; }
+    }
+  };
+
+  try
+  {
+    struct S
+    {
+      O *s;
+      constexpr S () : s { std::allocator <O> {}.allocate (1) } {}
+      constexpr ~S () { std::allocator <O> {}.deallocate (s, 1); }
+    };
+
+    auto s = S {};
+
+    ::new (s.s) O { -1 };
+  }
+  catch (E &)
+  {
+  }
+  return true;
+}
+
+static_assert (foo ());
index fb36dae25a6d3720e5e7c2efdbd85940d57af5fa..018adc0c4ede90dd059830ecc96d5f0daa8bb76e 100644 (file)
@@ -229,15 +229,16 @@ void* operator new[](std::size_t, void* __p)
   _GLIBCXX_TXN_SAFE _GLIBCXX_USE_NOEXCEPT
 { return __p; }
 
-#undef _GLIBCXX_PLACEMENT_CONSTEXPR
-
 // Default placement versions of operator delete.
-inline void operator delete  (void*, void*)
+_GLIBCXX_PLACEMENT_CONSTEXPR void operator delete  (void*, void*)
   _GLIBCXX_TXN_SAFE _GLIBCXX_USE_NOEXCEPT
 { }
-inline void operator delete[](void*, void*)
+_GLIBCXX_PLACEMENT_CONSTEXPR void operator delete[](void*, void*)
   _GLIBCXX_TXN_SAFE _GLIBCXX_USE_NOEXCEPT
 { }
+
+#undef _GLIBCXX_PLACEMENT_CONSTEXPR
+
 //@}
 } // extern "C++"