Simplify checks by caching symbol database Variable pointer in Token

This commit is contained in:
Robert Reif 2013-01-31 20:08:48 +01:00 committed by Daniel Marjamäki
parent e2faed355b
commit 94c953931d
5 changed files with 41 additions and 51 deletions

View File

@ -66,7 +66,7 @@ void Check64BitPortability::pointerassignment()
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
if (Token::Match(tok, "return %var% [;+]")) {
const Variable *var = symbolDatabase->getVariableFromVarId(tok->next()->varId());
const Variable *var = tok->next()->variable();
if (retPointer && isint(var))
returnIntegerError(tok);
else if (!retPointer && isaddr(var))
@ -81,8 +81,8 @@ void Check64BitPortability::pointerassignment()
for (const Token *tok = scope->classStart; tok && tok != scope->classEnd; tok = tok->next()) {
if (Token::Match(tok, "[;{}] %var% = %var% [;+]")) {
const Variable *var1(symbolDatabase->getVariableFromVarId(tok->next()->varId()));
const Variable *var2(symbolDatabase->getVariableFromVarId(tok->tokAt(3)->varId()));
const Variable *var1(tok->next()->variable());
const Variable *var2(tok->tokAt(3)->variable());
if (isaddr(var1) && isint(var2) && tok->strAt(4) != "+")
assignmentIntegerToAddressError(tok->next());

View File

@ -36,15 +36,13 @@ void CheckAssignIf::assignIf()
if (!_settings->isEnabled("style"))
return;
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
if (tok->str() != "=")
continue;
if (Token::Match(tok->tokAt(-2), "[;{}] %var% =")) {
const unsigned int varid(tok->previous()->varId());
if (varid == 0)
const Variable *var = tok->previous()->variable();
if (var == 0)
continue;
char bitop = '\0';
@ -67,12 +65,7 @@ void CheckAssignIf::assignIf()
if (num < 0 && bitop == '|')
continue;
bool islocal = false;
const Variable *var = symbolDatabase->getVariableFromVarId(varid);
if (var && var->isLocal())
islocal = true;
assignIfParseScope(tok, tok->tokAt(4), varid, islocal, bitop, num);
assignIfParseScope(tok, tok->tokAt(4), var->varId(), var->isLocal(), bitop, num);
}
}
}

View File

@ -35,23 +35,23 @@ namespace {
}
bool CheckAutoVariables::isRefPtrArg(unsigned int varId)
bool CheckAutoVariables::isRefPtrArg(const Token *tok)
{
const Variable *var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(varId);
const Variable *var = tok->variable();
return(var && var->isArgument() && var->isReference() && var->isPointer());
}
bool CheckAutoVariables::isPtrArg(unsigned int varId)
bool CheckAutoVariables::isPtrArg(const Token *tok)
{
const Variable *var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(varId);
const Variable *var = tok->variable();
return(var && var->isArgument() && var->isPointer());
}
bool CheckAutoVariables::isAutoVar(unsigned int varId)
bool CheckAutoVariables::isAutoVar(const Token *tok)
{
const Variable *var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(varId);
const Variable *var = tok->variable();
if (!var || !var->isLocal() || var->isStatic())
return false;
@ -66,9 +66,9 @@ bool CheckAutoVariables::isAutoVar(unsigned int varId)
return true;
}
bool CheckAutoVariables::isAutoVarArray(unsigned int varId)
bool CheckAutoVariables::isAutoVarArray(const Token *tok)
{
const Variable *var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(varId);
const Variable *var = tok->variable();
return (var && var->isLocal() && !var->isStatic() && var->isArray());
}
@ -88,21 +88,21 @@ void CheckAutoVariables::autoVariables()
const Scope * scope = symbolDatabase->functionScopes[i];
for (const Token *tok = scope->classStart; tok && tok != scope->classEnd; tok = tok->next()) {
// Critical assignment
if (Token::Match(tok, "[;{}] %var% = & %var%") && isRefPtrArg(tok->next()->varId()) && isAutoVar(tok->tokAt(4)->varId())) {
const Variable * var = symbolDatabase->getVariableFromVarId(tok->tokAt(4)->varId());
if (Token::Match(tok, "[;{}] %var% = & %var%") && isRefPtrArg(tok->next()) && isAutoVar(tok->tokAt(4))) {
const Variable * var = tok->tokAt(4)->variable();
if (checkRvalueExpression(var, tok->tokAt(5)))
errorAutoVariableAssignment(tok->next(), false);
} else if (Token::Match(tok, "[;{}] * %var% = & %var%") && isPtrArg(tok->tokAt(2)->varId()) && isAutoVar(tok->tokAt(5)->varId())) {
const Variable * var = symbolDatabase->getVariableFromVarId(tok->tokAt(5)->varId());
} else if (Token::Match(tok, "[;{}] * %var% = & %var%") && isPtrArg(tok->tokAt(2)) && isAutoVar(tok->tokAt(5))) {
const Variable * var = tok->tokAt(5)->variable();
if (checkRvalueExpression(var, tok->tokAt(6)))
errorAutoVariableAssignment(tok->next(), false);
} else if (Token::Match(tok, "[;{}] %var% . %var% = & %var%")) {
// TODO: check if the parameter is only changed temporarily (#2969)
if (_settings->inconclusive) {
const Variable * var1 = symbolDatabase->getVariableFromVarId(tok->next()->varId());
const Variable * var1 = tok->next()->variable();
if (var1 && var1->isArgument() && var1->isPointer()) {
const Variable * var2 = symbolDatabase->getVariableFromVarId(tok->tokAt(6)->varId());
if (isAutoVar(tok->tokAt(6)->varId()) && checkRvalueExpression(var2, tok->tokAt(7)))
const Variable * var2 = tok->tokAt(6)->variable();
if (isAutoVar(tok->tokAt(6)) && checkRvalueExpression(var2, tok->tokAt(7)))
errorAutoVariableAssignment(tok->next(), true);
}
}
@ -110,42 +110,42 @@ void CheckAutoVariables::autoVariables()
} else if (Token::Match(tok, "[;{}] %var% . %var% = %var% ;")) {
// TODO: check if the parameter is only changed temporarily (#2969)
if (_settings->inconclusive) {
const Variable * var1 = symbolDatabase->getVariableFromVarId(tok->next()->varId());
const Variable * var1 = tok->next()->variable();
if (var1 && var1->isArgument() && var1->isPointer()) {
if (isAutoVarArray(tok->tokAt(5)->varId()))
if (isAutoVarArray(tok->tokAt(5)))
errorAutoVariableAssignment(tok->next(), true);
}
}
tok = tok->tokAt(5);
} else if (Token::Match(tok, "[;{}] * %var% = %var% ;")) {
const Variable * var1 = symbolDatabase->getVariableFromVarId(tok->tokAt(2)->varId());
const Variable * var1 = tok->tokAt(2)->variable();
if (var1 && var1->isArgument() && Token::Match(var1->nameToken()->tokAt(-3), "%type% * *")) {
if (isAutoVarArray(tok->tokAt(4)->varId()))
if (isAutoVarArray(tok->tokAt(4)))
errorAutoVariableAssignment(tok->next(), false);
}
tok = tok->tokAt(4);
} else if (Token::Match(tok, "[;{}] %var% [") && Token::Match(tok->linkAt(2), "] = & %var%") && isPtrArg(tok->next()->varId()) && isAutoVar(tok->linkAt(2)->tokAt(3)->varId())) {
} else if (Token::Match(tok, "[;{}] %var% [") && Token::Match(tok->linkAt(2), "] = & %var%") && isPtrArg(tok->next()) && isAutoVar(tok->linkAt(2)->tokAt(3))) {
const Token* const varTok = tok->linkAt(2)->tokAt(3);
const Variable * var = symbolDatabase->getVariableFromVarId(varTok->varId());
const Variable * var = varTok->variable();
if (checkRvalueExpression(var, varTok->next()))
errorAutoVariableAssignment(tok->next(), false);
}
// Critical return
else if (Token::Match(tok, "return & %var% ;") && isAutoVar(tok->tokAt(2)->varId())) {
else if (Token::Match(tok, "return & %var% ;") && isAutoVar(tok->tokAt(2))) {
errorReturnAddressToAutoVariable(tok);
} else if (Token::Match(tok, "return & %var% [") &&
Token::simpleMatch(tok->linkAt(3), "] ;") &&
isAutoVarArray(tok->tokAt(2)->varId())) {
isAutoVarArray(tok->tokAt(2))) {
errorReturnAddressToAutoVariable(tok);
} else if (Token::Match(tok, "return & %var% ;") && tok->tokAt(2)->varId()) {
const Variable * var1 = symbolDatabase->getVariableFromVarId(tok->tokAt(2)->varId());
const Variable * var1 = tok->tokAt(2)->variable();
if (var1 && var1->isArgument() && var1->typeEndToken()->str() != "&")
errorReturnAddressOfFunctionParameter(tok, tok->strAt(2));
}
// Invalid pointer deallocation
else if (Token::Match(tok, "free ( %var% ) ;") || Token::Match(tok, "delete [| ]| (| %var% !![")) {
tok = Token::findmatch(tok->next(), "%var%");
if (isAutoVarArray(tok->varId()))
if (isAutoVarArray(tok))
errorInvalidDeallocation(tok);
}
}
@ -171,8 +171,7 @@ void CheckAutoVariables::returnPointerToLocalArray()
for (const Token *tok2 = scope->classStart->next(); tok2 && tok2 != scope->classEnd; tok2 = tok2->next()) {
// Return pointer to local array variable..
if (Token::Match(tok2, "return %var% ;")) {
const unsigned int varid = tok2->next()->varId();
if (isAutoVarArray(varid)) {
if (isAutoVarArray(tok2->next())) {
errorReturnPointerToLocalArray(tok2);
}
}
@ -285,10 +284,8 @@ void CheckAutoVariables::returnReference()
// return..
if (Token::Match(tok2, "return %var% ;")) {
// is the returned variable a local variable?
const unsigned int varid1 = tok2->next()->varId();
const Variable *var1 = symbolDatabase->getVariableFromVarId(varid1);
if (isAutoVar(varid1)) {
if (isAutoVar(tok2->next())) {
const Variable *var1 = tok2->next()->variable();
// If reference variable is used, check what it references
if (Token::Match(var1->nameToken(), "%var% [=(]")) {
const Token *tok3 = var1->nameToken()->tokAt(2);
@ -297,7 +294,7 @@ void CheckAutoVariables::returnReference()
// Only report error if variable that is referenced is
// a auto variable
if (!isAutoVar(tok3->varId()))
if (!isAutoVar(tok3))
continue;
}

View File

@ -63,10 +63,10 @@ public:
void returnReference();
private:
bool isRefPtrArg(unsigned int varId);
bool isPtrArg(unsigned int varId);
bool isAutoVar(unsigned int varId);
bool isAutoVarArray(unsigned int varId);
bool isRefPtrArg(const Token *tok);
bool isPtrArg(const Token *tok);
bool isAutoVar(const Token *tok);
bool isAutoVarArray(const Token *tok);
/**
* Returning a temporary object?

View File

@ -1046,7 +1046,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const std::vector<std::str
}
} else if ((varid > 0 && Token::Match(tok, "strcpy|strcat ( %varid% , %var% )", varid)) ||
(varid == 0 && Token::Match(tok, ("strcpy|strcat ( " + varnames + " , %var% )").c_str()))) {
const Variable *var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(tok->tokAt(4)->varId());
const Variable *var = tok->tokAt(4)->variable();
if (var && var->isArray() && var->dimensions().size() == 1) {
const std::size_t len = (std::size_t)var->dimension(0);
if (total_size > 0 && len > (unsigned int)total_size) {
@ -1915,7 +1915,7 @@ void CheckBufferOverrun::negativeIndex()
tok2 = tok2->previous()->link();
if (tok2->previous() && tok2->previous()->varId()) {
const Variable *var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(tok2->previous()->varId());
const Variable *var = tok2->previous()->variable();
if (var && var->isArray())
negativeIndexError(tok, index);
}