Class checking : Check that base class destructors are virtual. Experimental
This commit is contained in:
parent
bcccb4bc91
commit
4493400c49
|
@ -598,6 +598,7 @@ void CheckClass::CheckMemset()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -616,5 +617,53 @@ void CheckClass::CheckOperatorEq1()
|
||||||
_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%");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,9 @@ public:
|
||||||
|
|
||||||
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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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)"
|
||||||
|
|
Loading…
Reference in New Issue