Refactorized CheckOther::checkRedundantCopy():

- Iterate over variable list instead of token list
- Don't stop whole checking after bailing out (continue; instead of break;)
- Support types with qualified names
This commit is contained in:
PKEuS 2013-03-05 06:53:09 -08:00
parent 2a312efd6e
commit 5bdb74ca40
1 changed files with 21 additions and 23 deletions

View File

@ -3805,34 +3805,32 @@ void CheckOther::checkRedundantCopy()
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
for (const Token *tok = _tokenizer->tokens(); tok; tok=tok->next()) { for (std::size_t i = 0; i < symbolDatabase->getVariableListSize(); i++) {
const char *expect_end_token; const Variable* var = symbolDatabase->getVariableFromVarId(i);
if (Token::Match(tok, "const %type% %var% =")) {
//match "const A a =" usage
expect_end_token = ";";
} else if (Token::Match(tok, "const %type% %var% (")) {
//match "const A a (" usage
expect_end_token = ")";
} else {
continue;
}
if (tok->strAt(1) == tok->strAt(4)) //avoid "const A a = A();" if (!var || var->isReference() || !var->isConst() || var->isPointer() || !var->type()) // bailout if var is of standard type, if it is a pointer or non-const
continue; continue;
if (!symbolDatabase->isClassOrStruct(tok->next()->str())) //avoid when %type% is standard type
const Token* startTok = var->nameToken();
const Token* endToken;
if (startTok->strAt(1) == "=") // %type% %var% = ... ;
endToken = Token::findsimplematch(startTok->tokAt(2), ";");
else if (startTok->strAt(1) == "(") // %type% %var%(...)
endToken = startTok->linkAt(1);
else
continue; continue;
const Token *var_tok = tok->tokAt(2);
tok = tok->tokAt(4); const Token* tok = startTok->tokAt(2);
while (tok &&Token::Match(tok,"%var% .")) while (tok && Token::Match(tok, "%var% .|::"))
tok = tok->tokAt(2); tok = tok->tokAt(2);
if (!Token::Match(tok, "%var% (")) if (!Token::Match(tok, "%var% ("))
break; continue;
const Token *match_end = (tok->next()->link()!=NULL)?tok->next()->link()->next():NULL; if (tok->linkAt(1)->next() != endToken) // bailout for usage like "const A a = getA()+3"
if (match_end==NULL || !Token::Match(match_end,expect_end_token)) //avoid usage like "const A a = getA()+3" continue;
break;
const Function* func = tok->function(); const Function* func = tok->function();
if (func && func->tokenDef->previous() && func->tokenDef->previous()->str() == "&") { if (func && func->tokenDef->strAt(-1) == "&") {
redundantCopyError(var_tok,var_tok->str()); redundantCopyError(startTok, startTok->str());
} }
} }
} }