change CheckClass::operatorEqToSelf to make better use of the symbol database
This commit is contained in:
parent
cf65a73c47
commit
a39444a40f
|
@ -965,6 +965,9 @@ void CheckClass::operatorEqToSelf()
|
||||||
|
|
||||||
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope)
|
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope)
|
||||||
{
|
{
|
||||||
|
if (!scope->isClassOrStruct())
|
||||||
|
continue;
|
||||||
|
|
||||||
std::list<Function>::const_iterator func;
|
std::list<Function>::const_iterator func;
|
||||||
|
|
||||||
// skip classes with multiple inheritance
|
// skip classes with multiple inheritance
|
||||||
|
@ -979,32 +982,13 @@ void CheckClass::operatorEqToSelf()
|
||||||
if (Token::Match(func->tokenDef->tokAt(-3), ";|}|{|public:|protected:|private: %type% &") &&
|
if (Token::Match(func->tokenDef->tokAt(-3), ";|}|{|public:|protected:|private: %type% &") &&
|
||||||
func->tokenDef->strAt(-2) == scope->className)
|
func->tokenDef->strAt(-2) == scope->className)
|
||||||
{
|
{
|
||||||
// check for proper function parameter signature
|
// find the parameter name
|
||||||
if ((Token::Match(func->tokenDef->next(), "( const %var% & )") ||
|
const Token *rhs = func->argumentList.begin()->nameToken();
|
||||||
Token::Match(func->tokenDef->next(), "( const %var% & %var% )")) &&
|
|
||||||
func->tokenDef->strAt(3) == scope->className)
|
if (!hasAssignSelf(&(*func), rhs))
|
||||||
{
|
{
|
||||||
// find the parameter name
|
if (hasDeallocation(&(*func)))
|
||||||
const Token *rhs = func->token;
|
operatorEqToSelfError(func->token);
|
||||||
while (rhs->str() != "&")
|
|
||||||
rhs = rhs->next();
|
|
||||||
rhs = rhs->next();
|
|
||||||
|
|
||||||
// find the ')'
|
|
||||||
const Token *tok = func->token->next()->link();
|
|
||||||
const Token *tok1 = tok;
|
|
||||||
|
|
||||||
if (tok1 && tok1->tokAt(1) && tok1->tokAt(1)->str() == "{" && tok1->tokAt(1)->link())
|
|
||||||
{
|
|
||||||
const Token *first = tok1->tokAt(1);
|
|
||||||
const Token *last = first->link();
|
|
||||||
|
|
||||||
if (!hasAssignSelf(first, last, rhs))
|
|
||||||
{
|
|
||||||
if (hasDeallocation(first, last))
|
|
||||||
operatorEqToSelfError(tok);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1012,7 +996,7 @@ void CheckClass::operatorEqToSelf()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckClass::hasDeallocation(const Token *first, const Token *last)
|
bool CheckClass::hasDeallocation(const Function *func)
|
||||||
{
|
{
|
||||||
// This function is called when no simple check was found for assignment
|
// This function is called when no simple check was found for assignment
|
||||||
// to self. We are currently looking for a specific sequence of:
|
// to self. We are currently looking for a specific sequence of:
|
||||||
|
@ -1021,7 +1005,8 @@ bool CheckClass::hasDeallocation(const Token *first, const Token *last)
|
||||||
// Unfortunately, this is necessary to prevent false positives.
|
// Unfortunately, this is necessary to prevent false positives.
|
||||||
// This check needs to do careful analysis someday to get this
|
// This check needs to do careful analysis someday to get this
|
||||||
// correct with a high degree of certainty.
|
// correct with a high degree of certainty.
|
||||||
for (const Token *tok = first; tok && (tok != last); tok = tok->next())
|
const Token *last = func->start->link();
|
||||||
|
for (const Token *tok = func->start; tok && (tok != last); tok = tok->next())
|
||||||
{
|
{
|
||||||
// check for deallocating memory
|
// check for deallocating memory
|
||||||
if (Token::Match(tok, "{|;|, free ( %var%"))
|
if (Token::Match(tok, "{|;|, free ( %var%"))
|
||||||
|
@ -1086,9 +1071,10 @@ bool CheckClass::hasDeallocation(const Token *first, const Token *last)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckClass::hasAssignSelf(const Token *first, const Token *last, const Token *rhs)
|
bool CheckClass::hasAssignSelf(const Function *func, const Token *rhs)
|
||||||
{
|
{
|
||||||
for (const Token *tok = first; tok && tok != last; tok = tok->next())
|
const Token *last = func->start->link();
|
||||||
|
for (const Token *tok = func->start; tok && tok != last; tok = tok->next())
|
||||||
{
|
{
|
||||||
if (Token::simpleMatch(tok, "if ("))
|
if (Token::simpleMatch(tok, "if ("))
|
||||||
{
|
{
|
||||||
|
|
|
@ -165,8 +165,8 @@ private:
|
||||||
void checkReturnPtrThis(const Scope *scope, const Function *func, const Token *tok, const Token *last);
|
void checkReturnPtrThis(const Scope *scope, const Function *func, const Token *tok, const Token *last);
|
||||||
|
|
||||||
// operatorEqToSelf helper functions
|
// operatorEqToSelf helper functions
|
||||||
bool hasDeallocation(const Token *first, const Token *last);
|
bool hasDeallocation(const Function *func);
|
||||||
bool hasAssignSelf(const Token *first, const Token *last, const Token *rhs);
|
bool hasAssignSelf(const Function *func, const Token *rhs);
|
||||||
|
|
||||||
// checkConst helper functions
|
// checkConst helper functions
|
||||||
bool isMemberVar(const Scope *scope, const Token *tok);
|
bool isMemberVar(const Scope *scope, const Token *tok);
|
||||||
|
|
Loading…
Reference in New Issue