virtual destructors : no errormessage if the derived class has no destructor or empty destructor
This commit is contained in:
parent
ee5e20ed1f
commit
612d0e56f2
|
@ -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%") )
|
||||||
|
|
|
@ -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 )
|
||||||
|
|
Loading…
Reference in New Issue