Class checking : Check that base class destructors are virtual. Experimental
This commit is contained in:
parent
bcccb4bc91
commit
4493400c49
|
@ -597,7 +597,8 @@ void CheckClass::CheckMemset()
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
@ -615,6 +616,54 @@ void CheckClass::CheckOperatorEq1()
|
|||
ostr << _tokenizer->fileLine(tok) << ": 'operator=' should return something";
|
||||
_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%");
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -38,6 +38,9 @@ public:
|
|||
void CheckMemset();
|
||||
|
||||
void CheckOperatorEq1(); // Warning upon "void operator=(.."
|
||||
|
||||
// The destructor in a base class should be virtual
|
||||
void virtualDestructor();
|
||||
|
||||
private:
|
||||
struct VAR
|
||||
|
|
|
@ -261,6 +261,9 @@ void CppCheck::checkFile(const std::string &code, const char FileName[])
|
|||
// Check that all class constructors are ok.
|
||||
checkClass.CheckConstructors();
|
||||
|
||||
// Check that all base classes have virtual destructors
|
||||
checkClass.virtualDestructor();
|
||||
|
||||
if (_settings._showAll)
|
||||
{
|
||||
// Check for "if (a=b)"
|
||||
|
|
Loading…
Reference in New Issue