https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100861
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Severity|normal |enhancement Status|UNCONFIRMED |NEW Component|c++ |middle-end Last reconfirmed| |2021-06-01 CC| |msebor at gcc dot gnu.org Ever confirmed|0 |1 Blocks| |100406 --- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> --- The warning doesn't do anything special with destroying operator delete or any other kinds of the operators (other than scalar vs array). It triggers for this test case because it sees the result of ::operator new() being passed to Widget::operator delete (Widget*). If Widget::operator delete() is inlined (e.g., declared with attribute always_inline) the warning goes away just as long as the operator doesn't pass the pointer to the wrong overload of delete. Alternatively, if Widget defines a non-inline member operator new() that also prevents the warning because calls to both operators match. With that, I'm not sure that suppressing the warning for a destroying operator delete() would be a good solution. It seems to me that the right fix is to solve the broader problem where one of the operators is inlined and the other isn't (similar to pr100485, except with the definitions of both operators available in the same translation unit). Until/unless a solution is developed I would suggest to either define the destroying operator delete inline and have it call an out-of-line function to do the work (as shown below) or to force the inlining of the destroying delete. struct Widget { const WidgetKind Kind : 4; unsigned OtherThings : 28; Widget(WidgetKind k) : Kind(k) {} void operator delete(Widget *widget, std::destroying_delete_t) { destroy_delete (widget); } static __attribute__ ((noinline)) void destroy_delete (Widget *); }; Referenced Bugs: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100406 [Bug 100406] bogus/missing -Wmismatched-new-delete