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 > >
