diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index f32a0d782..9be1870f7 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -1639,7 +1639,7 @@ void CheckClass::virtualDestructor() { // This error should only be given if: // * base class doesn't have virtual destructor - // * derived class has non-empty destructor + // * derived class has non-empty destructor (only c++03, in c++11 it's UB see paragraph 3 in [expr.delete]) // * base class is deleted // unless inconclusive in which case: // * base class has virtual members but doesn't have virtual destructor @@ -1665,16 +1665,19 @@ void CheckClass::virtualDestructor() continue; } - // Find the destructor - const Function *destructor = scope->getDestructor(); + // Check if destructor is empty and non-empty .. + if (mSettings->standards.cpp <= Standards::CPP03) { + // Find the destructor + const Function *destructor = scope->getDestructor(); - // Check for destructor with implementation - if (!destructor || !destructor->hasBody()) - continue; + // Check for destructor with implementation + if (!destructor || !destructor->hasBody()) + continue; - // Empty destructor - if (destructor->token->linkAt(3) == destructor->token->tokAt(4)) - continue; + // Empty destructor + if (destructor->token->linkAt(3) == destructor->token->tokAt(4)) + continue; + } const Token *derived = scope->classDef; const Token *derivedClass = derived->next(); diff --git a/test/testclass.cpp b/test/testclass.cpp index 0e4fb2d0c..794f9b2c2 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -2497,35 +2497,35 @@ private: } void virtualDestructor4() { - // Derived class doesn't have a destructor => no error + // Derived class doesn't have a destructor => undefined behaviour according to paragraph 3 in [expr.delete] checkVirtualDestructor("class Base { public: ~Base(); };\n" "class Derived : public Base { };" "Base *base = new Derived;\n" "delete base;"); - ASSERT_EQUALS("", errout.str()); + ASSERT_EQUALS("[test.cpp:1]: (error) Class 'Base' which is inherited by class 'Derived' does not have a virtual destructor.\n", errout.str()); checkVirtualDestructor("class Base { public: ~Base(); };\n" "class Derived : private Fred, public Base { };" "Base *base = new Derived;\n" "delete base;"); - ASSERT_EQUALS("", errout.str()); + ASSERT_EQUALS("[test.cpp:1]: (error) Class 'Base' which is inherited by class 'Derived' does not have a virtual destructor.\n", errout.str()); } void virtualDestructor5() { - // Derived class has empty destructor => no error + // Derived class has empty destructor => undefined behaviour according to paragraph 3 in [expr.delete] checkVirtualDestructor("class Base { public: ~Base(); };\n" "class Derived : public Base { public: ~Derived() {} };" "Base *base = new Derived;\n" "delete base;"); - ASSERT_EQUALS("", errout.str()); + ASSERT_EQUALS("[test.cpp:1]: (error) Class 'Base' which is inherited by class 'Derived' does not have a virtual destructor.\n", errout.str()); checkVirtualDestructor("class Base { public: ~Base(); };\n" "class Derived : public Base { public: ~Derived(); }; Derived::~Derived() {}" "Base *base = new Derived;\n" "delete base;"); - ASSERT_EQUALS("", errout.str()); + ASSERT_EQUALS("[test.cpp:1]: (error) Class 'Base' which is inherited by class 'Derived' does not have a virtual destructor.\n", errout.str()); } void virtualDestructor6() {