On Wed, 19 Nov 2025, 08:16 Jakub Jelinek, <[email protected]> wrote:

> Hi!
>
> 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.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>

OK thanks.



> 2025-11-19  Jakub Jelinek  <[email protected]>
>
>         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.
>
> --- libstdc++-v3/libsupc++/new.jj       2025-09-06 11:18:17.987614541 +0200
> +++ libstdc++-v3/libsupc++/new  2025-11-18 15:40:39.752001426 +0100
> @@ -229,15 +229,16 @@ void* operator new[](std::size_t, void*
>    _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++"
>
> --- gcc/testsuite/g++.dg/cpp26/constexpr-eh17.C.jj      2025-11-18
> 15:08:17.232427900 +0100
> +++ gcc/testsuite/g++.dg/cpp26/constexpr-eh17.C 2025-11-18
> 15:08:12.663492819 +0100
> @@ -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 ());
>
>         Jakub
>
>

Reply via email to