From a39444a40f9db40a1441988286f792e9670dbf35 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Thu, 31 Mar 2011 19:53:35 -0400 Subject: [PATCH] change CheckClass::operatorEqToSelf to make better use of the symbol database --- lib/checkclass.cpp | 44 +++++++++++++++----------------------------- lib/checkclass.h | 4 ++-- 2 files changed, 17 insertions(+), 31 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 890cbbb2c..43b5fae14 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -965,6 +965,9 @@ void CheckClass::operatorEqToSelf() for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) { + if (!scope->isClassOrStruct()) + continue; + std::list::const_iterator func; // skip classes with multiple inheritance @@ -979,32 +982,13 @@ void CheckClass::operatorEqToSelf() if (Token::Match(func->tokenDef->tokAt(-3), ";|}|{|public:|protected:|private: %type% &") && func->tokenDef->strAt(-2) == scope->className) { - // check for proper function parameter signature - if ((Token::Match(func->tokenDef->next(), "( const %var% & )") || - Token::Match(func->tokenDef->next(), "( const %var% & %var% )")) && - func->tokenDef->strAt(3) == scope->className) + // find the parameter name + const Token *rhs = func->argumentList.begin()->nameToken(); + + if (!hasAssignSelf(&(*func), rhs)) { - // find the parameter name - const Token *rhs = 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); - } - } + if (hasDeallocation(&(*func))) + operatorEqToSelfError(func->token); } } } @@ -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 // 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. // This check needs to do careful analysis someday to get this // 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 if (Token::Match(tok, "{|;|, free ( %var%")) @@ -1086,9 +1071,10 @@ bool CheckClass::hasDeallocation(const Token *first, const Token *last) 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 (")) { diff --git a/lib/checkclass.h b/lib/checkclass.h index 738cbb891..6c4f41823 100644 --- a/lib/checkclass.h +++ b/lib/checkclass.h @@ -165,8 +165,8 @@ private: void checkReturnPtrThis(const Scope *scope, const Function *func, const Token *tok, const Token *last); // operatorEqToSelf helper functions - bool hasDeallocation(const Token *first, const Token *last); - bool hasAssignSelf(const Token *first, const Token *last, const Token *rhs); + bool hasDeallocation(const Function *func); + bool hasAssignSelf(const Function *func, const Token *rhs); // checkConst helper functions bool isMemberVar(const Scope *scope, const Token *tok);