https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117370
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Created attachment 59503 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=59503&action=edit gcc15-pr117370-1.patch The C++ FE marks now 12 out of the 20 global replaceable operator new/delete with DECL_IS_REPLACEABLE_OPERATOR (in particular the ones that it predeclares), but doesn't mark those with const std::nothrow_t& last argument. This patch marks even those, on the suggestion from Jason in grok_op_properties rather than by predeclaring those too. The patch alone isn't enough, we need more code in tree-ssa-dce.cc or elsewhere. The thing is that for the throwing operator new, evrp figures out it will never return NULL and so will optimize away the if (a) conditional around operator delete to if (true). But that is not the case for the nothrow, the function can return NULL and then the question is what we are willing to optimize away, if just the case where only the delete call is skipped and perhaps clobber and maybe some dead stores to it before delete, or if the operator new returning NULL branch can be simply optimized away no matter what it does. That isn't really specific to the nothrow operator new, void foo (int x) { int *a = (int *) __builtin_malloc (x); if (a) __builtin_free (a); } is exactly the same thing, we also don't DCE that.