http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53596
--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> 2012-06-06 22:43:23 UTC --- The warning is valid, the fact Base is protected is irrelevant, you're not using delete with a Base* operand. Consider: class MoreDerived : public Derived { public: ~Derived() { std::cout << "MoreDerived::~MoreDerived()" << std::endl; } }; int main() { Derived* morederived = new MoreDerived(); morederived->foo(); delete morederived; // undefined behaviour } Now the warning is entirely correct, you are deleting a Derived* which is a polymorphic type without a virtual destructor, so the program has undefined behaviour. That's substantially the same as your example, on the line: delete derived; the compiler doesn't know that the Derived* points to a Derived or a MoreDerived, so it warns you it might cause undefined behaviour. N.B. Clang (known for much better diagnostics than MSVC or Sun CC) also warns for your example: w.cc:19:3: warning: delete called on 'Derived' that has virtual functions but non-virtual destructor [-Wdelete-non-virtual-dtor] delete derived; // legal, there must be no warning! ^ 1 warning generated.