https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118577
Bug ID: 118577 Summary: Deleted dtor trying to override non-deleted one with user-defined 'operator delete' is not forbidden Product: gcc Version: 15.0 Status: UNCONFIRMED Keywords: accepts-invalid Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: rush102333 at gmail dot com Target Milestone: --- Consider the following code: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ struct A { void operator delete(void *, int); }; struct B : /*mut1*/private A { virtual ~B(); }; struct C : /*mut1*/private B {}; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ First, gcc and clang agree that this should be rejected if 'A::operator delete' has the same parameter list as the default one like 'operator delete(void *)': ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <source>:7:8: error: deleted function 'virtual C::~C()' overriding non-deleted function 7 | struct C : private B {}; | ^ <source>:5:11: note: overridden function is 'virtual B::~B()' 5 | virtual ~B(); | ^ <source>:7:8: note: 'virtual C::~C()' is implicitly deleted because the default definition would be ill-formed: 7 | struct C : private B {}; | ^ <source>:7:8: error: 'static void A::operator delete(void*)' is private within this context <source>:4:8: note: declared private here 4 | struct B : private A { | ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ But gcc will not reject it anymore if the argument list of 'A::operator delete' changes(as shown in the example above): https://godbolt.org/z/vahT4rEzE It is even more confusing that EDG and MSVC seem to always accept that.