https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100861
Bug ID: 100861 Summary: False positive -Wmismatched-new-delete with destroying operator delete Product: gcc Version: 12.0 Status: UNCONFIRMED Keywords: diagnostic Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: josephcsible at gmail dot com Target Milestone: --- Currently, code like "Base *b = new Derived; delete b;" gives a -Wmismatched-new-delete warning, unless Base has a virtual destructor. One of the use cases for C++20's destroying operator delete is to make this safe without needing a virtual destructor, so this warning should be suppressed if Base has a destroying operator delete. Here's a modified version of the code at http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0722r1.html that will unnecessarily cause this warning (compile with -std=c++20 -Wall): #include <new> enum class WidgetKind { Grommet, Wingnut }; struct Widget { const WidgetKind Kind : 4; unsigned OtherThings : 28; Widget(WidgetKind k) : Kind(k) {} void operator delete(Widget *, std::destroying_delete_t); }; struct Grommet : Widget { Grommet() : Widget(WidgetKind::Grommet) {} }; struct Wingnut : Widget { Wingnut() : Widget(WidgetKind::Wingnut) {} }; void Widget::operator delete(Widget *widget, std::destroying_delete_t) { switch (widget->Kind) { case WidgetKind::Grommet: static_cast<Grommet*>(widget)->~Grommet(); ::operator delete(widget, sizeof(Grommet)); return; case WidgetKind::Wingnut: static_cast<Wingnut*>(widget)->~Wingnut(); ::operator delete(widget, sizeof(Wingnut)); return; } } int main() { Widget *widget = new Grommet; delete widget; }