https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100861
--- Comment #3 from Martin Sebor <msebor at gcc dot gnu.org> --- The virtual dtor forces an out-of-line call to the Grommet dtor which then calls ::operator delete(), so the warning has nothing to complain about. It sees this code (compile with -fdump-tree-optimized=/dev/stdout): int main () { void * _3; <bb 2> [local count: 1073741824]: _3 = operator new (16); MEM[(struct Widget *)_3].Kind = 0; MEM[(struct Grommet *)_3].D.2504._vptr.Widget = &MEM <int (*) ()[4]> [(void *)&_ZTV7Grommet + 16B]; Grommet::~Grommet (_3); return 0; } whereas with the original test case it sees: int main () { struct destroying_delete_t D.2584; void * _3; <bb 2> [local count: 1073741824]: _3 = operator new (4); Widget::operator delete (_3, D.2584); <<< warning here return 0; }