Class checking : Check that base class destructors are virtual. Experimental

This commit is contained in:
Daniel Marjamäki 2008-12-06 17:34:34 +00:00
parent bcccb4bc91
commit 4493400c49
3 changed files with 57 additions and 2 deletions

View File

@ -597,7 +597,8 @@ void CheckClass::CheckMemset()
} }
} }
} }
} }
//---------------------------------------------------------------------------
@ -615,6 +616,54 @@ void CheckClass::CheckOperatorEq1()
ostr << _tokenizer->fileLine(tok) << ": 'operator=' should return something"; ostr << _tokenizer->fileLine(tok) << ": 'operator=' should return something";
_errorLogger->reportErr(ostr.str()); _errorLogger->reportErr(ostr.str());
} }
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// A destructor in a base class should be virtual
//---------------------------------------------------------------------------
void CheckClass::virtualDestructor()
{
const TOKEN *derived = TOKEN::findmatch(_tokenizer->tokens(), "class %var% : public %var%");
while (derived)
{
// Name of base class..
const char *baseName[2];
baseName[0] = derived->strAt( 4 );
baseName[1] = 0;
// Find the destructor for the base class.
const TOKEN *base = TOKEN::findmatch(_tokenizer->tokens(), "%any% ~ %var1% (", baseName);
while (base && TOKEN::Match(base, "::"))
base = TOKEN::findmatch(base->next, "%any% ~ %var1% (", baseName);
// Check that there is a destructor..
if ( ! base )
{
// Is the class declaration available?
base = TOKEN::findmatch(_tokenizer->tokens(), "class %var1% :|{", baseName);
if ( base )
{
std::ostringstream errmsg;
errmsg << _tokenizer->fileLine(base) << ": Base class " << baseName[0] << " doesn't have a virtual destructor";
_errorLogger->reportErr(errmsg.str());
}
}
// There is a destructor. Check that it's virtual..
else if ( ! TOKEN::Match(base, "virtual") )
{
std::ostringstream errmsg;
errmsg << _tokenizer->fileLine(base) << ": The destructor for the base class " << baseName[0] << " is not virtual";
_errorLogger->reportErr(errmsg.str());
}
derived = TOKEN::findmatch(derived->next, "class %var% : public %var%");
}
} }
//---------------------------------------------------------------------------

View File

@ -38,6 +38,9 @@ public:
void CheckMemset(); void CheckMemset();
void CheckOperatorEq1(); // Warning upon "void operator=(.." void CheckOperatorEq1(); // Warning upon "void operator=(.."
// The destructor in a base class should be virtual
void virtualDestructor();
private: private:
struct VAR struct VAR

View File

@ -261,6 +261,9 @@ void CppCheck::checkFile(const std::string &code, const char FileName[])
// Check that all class constructors are ok. // Check that all class constructors are ok.
checkClass.CheckConstructors(); checkClass.CheckConstructors();
// Check that all base classes have virtual destructors
checkClass.virtualDestructor();
if (_settings._showAll) if (_settings._showAll)
{ {
// Check for "if (a=b)" // Check for "if (a=b)"