http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53596
--- Comment #3 from kim.walisch at gmail dot com 2012-06-07 07:31:41 UTC --- Hi, thanks for your answer but I still think it is a bug. Here are my reasons: 1) You mention that Clang also warns for my example but this seems to be a bug in Clang, see http://lists.cs.uiuc.edu/pipermail/llvmbugs/2012-March/022451.html 2) Herb Sutter wrote a Guru of the Week (GotW) article on this topic (http://www.gotw.ca/publications/mill18.htm), it says: Guideline #4: A base class destructor should be either public and virtual, or protected and nonvirtual. 3) If I modify 'virtual void foo()' to 'void foo()' in my previous example the warning vanishes, this makes no sense. terminal log: $ g++-4.7 -Wall test2.cpp $ ///////////////////////////////////////////////////////////////// // file: test2.cpp #include <iostream> class Base { protected: ~Base() { } }; class Derived : public Base { public: void foo() { std::cout << "Derived::foo()" << std::endl; } ~Derived() { std::cout << "Derived::~Derived()" << std::endl; } }; int main() { Derived* derived = new Derived(); derived->foo(); delete derived; // correct, no warning! return 0; } ///////////////////////////////////////////////////////////////// 4) In your MoreDerived example you can make the Derived dtor virtual, this way the protected non-virtual Base destructor is absolutely valid. ///////////////////////////////////////////////////////////////// // file: test3.cpp class Base { public: virtual void foo() = 0; protected: ~Base() { } }; class Derived : public Base { public: virtual void foo() { } virtual ~Derived() { } }; class MoreDerived : public Derived { public: ~MoreDerived() { } }; int main() { Derived* morederived = new MoreDerived(); morederived->foo(); delete morederived; // no warning, virtual Derived dtor return 0; } /////////////////////////////////////////////////////////////////