virtual destructors : no errormessage if the derived class has no destructor or empty destructor

This commit is contained in:
Daniel Marjamäki 2008-12-17 20:38:09 +00:00
parent ee5e20ed1f
commit 612d0e56f2
2 changed files with 40 additions and 5 deletions

View File

@ -689,6 +689,27 @@ void CheckClass::virtualDestructor()
const TOKEN *derived = _tokenizer->tokens(); const TOKEN *derived = _tokenizer->tokens();
while ((derived = TOKEN::findmatch(derived, pattern_classdecl)) != NULL) while ((derived = TOKEN::findmatch(derived, pattern_classdecl)) != NULL)
{ {
// Check that the derived class has a non empty destructor..
{
std::ostringstream destructorPattern;
destructorPattern << "~ " << derived->strAt(1) << " ( ) {";
const TOKEN *derived_destructor = TOKEN::findmatch( _tokenizer->tokens(), destructorPattern.str().c_str() );
// No destructor..
if ( ! derived_destructor )
{
derived = derived->next();
continue;
}
// Empty destructor..
if ( TOKEN::Match(derived_destructor, "~ %var% ( ) { }") )
{
derived = derived->next();
continue;
}
}
// Iterate through each base class... // Iterate through each base class...
derived = derived->tokAt(3); derived = derived->tokAt(3);
while ( TOKEN::Match(derived, "%var%") ) while ( TOKEN::Match(derived, "%var%") )

View File

@ -39,6 +39,7 @@ private:
TEST_CASE( virtualDestructor1 ); // Base class not found => no error TEST_CASE( virtualDestructor1 ); // Base class not found => no error
TEST_CASE( virtualDestructor2 ); // Base class doesn't have a destructor TEST_CASE( virtualDestructor2 ); // Base class doesn't have a destructor
TEST_CASE( virtualDestructor3 ); // Base class has a destructor, but it's not virtual TEST_CASE( virtualDestructor3 ); // Base class has a destructor, but it's not virtual
TEST_CASE( virtualDestructor4 ); // Derived class doesn't have a destructor => no error
} }
// Check that base classes have virtual destructors // Check that base classes have virtual destructors
@ -76,11 +77,11 @@ private:
// Base class doesn't have a destructor // Base class doesn't have a destructor
checkVirtualDestructor("class Base { };\n" checkVirtualDestructor("class Base { };\n"
"class Derived : public Base { };"); "class Derived : public Base { public: ~Derived() { (void)11; } };");
ASSERT_EQUALS( std::string("[test.cpp:1]: Base class Base doesn't have a virtual destructor\n"), errout.str() ); ASSERT_EQUALS( std::string("[test.cpp:1]: Base class Base doesn't have a virtual destructor\n"), errout.str() );
checkVirtualDestructor("class Base { };\n" checkVirtualDestructor("class Base { };\n"
"class Derived : Base { };"); "class Derived : Base { public: ~Derived() { (void)11; } };");
ASSERT_EQUALS( std::string(""), errout.str() ); ASSERT_EQUALS( std::string(""), errout.str() );
} }
@ -89,13 +90,26 @@ private:
// Base class has a destructor, but it's not virtual // Base class has a destructor, but it's not virtual
checkVirtualDestructor("class Base { public: ~Base(); };\n" checkVirtualDestructor("class Base { public: ~Base(); };\n"
"class Derived : public Base { };"); "class Derived : public Base { public: ~Derived() { (void)11; } };");
ASSERT_EQUALS( std::string("[test.cpp:1]: The destructor for the base class Base is not virtual\n"), errout.str() ); ASSERT_EQUALS( std::string("[test.cpp:1]: The destructor for the base class Base is not virtual\n"), errout.str() );
checkVirtualDestructor("class Base { public: ~Base(); };\n" checkVirtualDestructor("class Base { public: ~Base(); };\n"
"class Derived : private Fred, public Base { };"); "class Derived : private Fred, public Base { public: ~Derived() { (void)11; } };");
ASSERT_EQUALS( std::string("[test.cpp:1]: The destructor for the base class Base is not virtual\n"), errout.str() ); ASSERT_EQUALS( std::string("[test.cpp:1]: The destructor for the base class Base is not virtual\n"), errout.str() );
} }
void virtualDestructor4()
{
// Derived class doesn't have a destructor => no error
checkVirtualDestructor("class Base { public: ~Base(); };\n"
"class Derived : public Base { };");
ASSERT_EQUALS( std::string(""), errout.str() );
checkVirtualDestructor("class Base { public: ~Base(); };\n"
"class Derived : private Fred, public Base { };");
ASSERT_EQUALS( std::string(""), errout.str() );
}
}; };
REGISTER_TEST( TestClass ) REGISTER_TEST( TestClass )