https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109442
--- Comment #9 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Jonathan Wakely from comment #8) > (In reply to Jonathan Wakely from comment #7) > > I think it's valid in theory. I don't know if it's possible for GCC to do it > > in practice. There doesn't seem to be anything the library can do to help, > > so WONTFIX. > > I think it's valid in theory because the implementation of std::vector is > opaque. It's not required to actually call operator new and operator delete > to obtain its storage, and so if the library and compiler collaborate to > provide storage some other way (e.g. using a stack buffer) then that's > allowed. > > But in practice it's hard to do that. > > Maybe it could be done with a new __builtin_elidable_operator_new and > __builtin_elidable_operator_delete pair that the library could use, or > attributes like you suggested in comment 4. That would allow the library to > say "I'm calling operator new and operator delete because I need to obtain > memory, but **these particular invocations** are not required to be visible > to the user, and therefore can be elided in the same way as new expressions > and delete expressions". > > In fact Clang's __builtin_operator_new already has exactly those semantics: > > https://clang.llvm.org/docs/LanguageExtensions.html#builtin-operator-new-and- > builtin-operator-delete > > And we already use those builtins if available, see PR 94295. > > So maybe what we need is to implement those. Yep, looking at that link this is exactly what would be needed. Note that in the middle-end we already see the calls to DECL_IS_REPLACEABLE_OPERATOR_NEW_P and replaceable operator delete. We just restrict all optimizations to calls emitted from new/delete expressions. I'm not sure the clang builtin is exactly providing the new/delete expression semantics resolving to replaceable operator new/delete or if there's other details. That is, I'm curious whether __builtin_operator_new provides more guarantees than a new/delete expression - the builtin semantics isn't very well defined unfortunately. It might be safer to go our own way here. I suppose the standard library could as well use malloc/free? Or is the standard library required to perform allocation with "replaceable operator new/delete"? (I suppose it helps not open-coding the exceptional cases)