Fixed #4535 (Simplify checks by caching symbol database Variable pointer in Token)

This commit is contained in:
Robert Reif 2013-02-06 06:39:58 +01:00 committed by Daniel Marjamäki
parent d9de7f7052
commit 42588e9729
7 changed files with 96 additions and 117 deletions

View File

@ -1401,7 +1401,7 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable()
std::string type;
// varid : The variable id for the array
unsigned int varid = 0;
const Variable *var = 0;
// nextTok : number of tokens used in variable declaration - used to skip to next statement.
int nextTok = 0;
@ -1413,48 +1413,44 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable()
if (Token::Match(tok, "[*;{}] %var% = new %type% [ %num% ]")) {
size = MathLib::toLongNumber(tok->strAt(6));
type = tok->strAt(4);
varid = tok->next()->varId();
var = tok->next()->variable();
nextTok = 8;
} else if (Token::Match(tok, "[*;{}] %var% = new %type% ( %num% )")) {
size = 1;
type = tok->strAt(4);
varid = tok->next()->varId();
var = tok->next()->variable();
nextTok = 8;
} else if (Token::Match(tok, "[;{}] %var% = %str% ;") &&
tok->next()->varId() > 0 &&
NULL != Token::findmatch(_tokenizer->tokens(), "[;{}] const| %type% * %varid% ;", tok->next()->varId())) {
size = 1 + int(tok->tokAt(3)->strValue().size());
type = "char";
varid = tok->next()->varId();
var = tok->next()->variable();
nextTok = 4;
} else if (Token::Match(tok, "[*;{}] %var% = malloc|alloca ( %num% ) ;")) {
size = MathLib::toLongNumber(tok->strAt(5));
type = "char"; // minimum type, typesize=1
varid = tok->next()->varId();
var = tok->next()->variable();
nextTok = 7;
if (varid > 0) {
// get type of variable
const Variable *var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(varid);
/** @todo false negatives: this may be too conservative */
if (!var || var->typeEndToken()->str() != "*" || var->typeStartToken()->next() != var->typeEndToken())
continue;
/** @todo false negatives: this may be too conservative */
if (!var || var->typeEndToken()->str() != "*" || var->typeStartToken()->next() != var->typeEndToken())
continue;
// get name of variable
type = var->typeStartToken()->str();
// get name of variable
type = var->typeStartToken()->str();
// malloc() gets count of bytes and not count of
// elements, so we should calculate count of elements
// manually
unsigned int sizeOfType = _tokenizer->sizeOfType(var->typeStartToken());
if (sizeOfType > 0)
size /= static_cast<int>(sizeOfType);
}
// malloc() gets count of bytes and not count of
// elements, so we should calculate count of elements
// manually
unsigned int sizeOfType = _tokenizer->sizeOfType(var->typeStartToken());
if (sizeOfType > 0)
size /= static_cast<int>(sizeOfType);
} else {
continue;
}
if (varid == 0)
if (var == 0)
continue;
Token sizeTok(0);
@ -1464,7 +1460,7 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable()
continue;
std::vector<std::string> v;
ArrayInfo temp(varid, tok->next()->str(), total_size / size, size);
ArrayInfo temp(var->varId(), tok->next()->str(), total_size / size, size);
checkScope(tok->tokAt(nextTok), v, temp);
}
}

View File

@ -89,15 +89,14 @@ void CheckExceptionSafety::deallocThrow()
break;
if (!Token::Match(tok, "%var% ;"))
continue;
const unsigned int varid(tok->varId());
if (varid == 0)
continue;
// we only look for global variables
const Variable* var = symbolDatabase->getVariableFromVarId(varid);
const Variable *var = tok->variable();
if (!var || !(var->isGlobal() || var->isStatic()))
continue;
const unsigned int varid(tok->varId());
// Token where throw occurs
const Token *ThrowToken = 0;
@ -172,7 +171,7 @@ void CheckExceptionSafety::checkCatchExceptionByValue()
// Find a pass-by-value declaration in the catch(), excluding basic types
// e.g. catch (std::exception err)
const Variable* var = symbolDatabase->getVariableFromVarId(i->classStart->tokAt(-2)->varId());
const Variable *var = i->classStart->tokAt(-2)->variable();
if (var && var->isClass() && !var->isPointer() && !var->isReference())
catchExceptionByValueError(i->classDef);
}

View File

@ -516,7 +516,7 @@ void CheckIO::checkWrongPrintfScanfArguments()
// Perform type checks
if (argListTok && Token::Match(argListTok->next(), "[,)]")) { // We can currently only check the type of arguments matching this simple pattern.
const Variable* variableInfo = symbolDatabase->getVariableFromVarId(argListTok->varId());
const Variable *variableInfo = argListTok->variable();
const Token* varTypeTok = variableInfo ? variableInfo->typeStartToken() : NULL;
if (varTypeTok && varTypeTok->str() == "static")
varTypeTok = varTypeTok->next();

View File

@ -311,7 +311,7 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken,
varInfo->erase(tok->varId());
// not a local variable nor argument?
const Variable *var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(tok->varId());
const Variable *var = tok->variable();
if (var && !var->isArgument() && !var->isLocal()) {
continue;
}

View File

@ -492,16 +492,14 @@ void CheckNullPointer::nullPointerLinkedList()
for (const Token *tok2 = tok1->tokAt(2); tok2 != end2; tok2 = tok2->next()) {
// Dereferencing a variable inside the "for" parentheses..
if (Token::Match(tok2, "%var% . %var%")) {
// Variable id for dereferenced variable
const unsigned int varid(tok2->varId());
if (varid == 0)
continue;
// Is this variable a pointer?
const Variable* var = symbolDatabase->getVariableFromVarId(varid);
const Variable *var = tok2->variable();
if (!var || !var->isPointer())
continue;
// Variable id for dereferenced variable
const unsigned int varid(tok2->varId());
if (Token::Match(tok2->tokAt(-2), "%varid% ?", varid))
continue;
@ -652,7 +650,7 @@ void CheckNullPointer::nullPointerStructByDeRefAndChec()
// is pointer local?
bool isLocal = false;
const Variable * var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(tok1->varId());
const Variable *var = tok1->variable();
if (!var)
continue;
if (var->isLocal() || var->isArgument())
@ -748,19 +746,17 @@ void CheckNullPointer::nullPointerByDeRefAndChec()
if (vartok->str() == "!")
vartok = vartok->next();
// Variable id for pointer
const unsigned int varid(vartok->varId());
if (varid == 0)
continue;
// Name of pointer
const std::string& varname(vartok->str());
const Variable* var = symbolDatabase->getVariableFromVarId(varid);
const Variable *var = vartok->variable();
// Check that variable is a pointer..
if (!var || !var->isPointer())
continue;
// Variable id for pointer
const unsigned int varid(vartok->varId());
// Name of pointer
const std::string& varname(vartok->str());
const Token * const decltok = var->nameToken();
bool inconclusive = false;
@ -932,16 +928,14 @@ void CheckNullPointer::nullPointerByCheckAndDeRef()
} else
continue;
// variable id for pointer
const unsigned int varid(vartok->varId());
if (varid == 0)
continue;
// Check if variable is a pointer
const Variable* var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(varid);
const Variable *var = vartok->variable();
if (!var || !var->isPointer())
continue;
// variable id for pointer
const unsigned int varid(vartok->varId());
const Scope* declScope = &*i;
while (declScope->nestedIn && var->scope() != declScope && declScope->type != Scope::eFunction)
declScope = declScope->nestedIn;
@ -1147,7 +1141,7 @@ void CheckNullPointer::nullConstantDereference()
else if (Token::Match(tok->previous(), "!!. %var% (") && (tok->previous()->str() != "::" || tok->strAt(-2) == "std")) {
if (Token::simpleMatch(tok->tokAt(2), "0 )") && tok->varId()) { // constructor call
const Variable* var = symbolDatabase->getVariableFromVarId(tok->varId());
const Variable *var = tok->variable();
if (var && !var->isPointer() && !var->isArray() && Token::Match(var->typeStartToken(), "std :: string|wstring !!::"))
nullPointerError(tok);
} else { // function call
@ -1173,24 +1167,21 @@ void CheckNullPointer::nullConstantDereference()
if (Token::simpleMatch(tok2, "std :: cin"))
nullPointerError(tok);
if (tok2 && tok2->varId() != 0) {
const Variable* var = symbolDatabase->getVariableFromVarId(tok2->varId());
const Variable *var = tok2->variable();
if (var && Token::Match(var->typeStartToken(), "std :: istream|ifstream|istringstream|wistringstream|stringstream|wstringstream|fstream|iostream"))
nullPointerError(tok);
}
}
unsigned int ovarid = 0;
const Variable *ovar = 0;
if (Token::Match(tok, "0 ==|!= %var%"))
ovarid = tok->tokAt(2)->varId();
ovar = tok->tokAt(2)->variable();
else if (Token::Match(tok, "%var% ==|!= 0"))
ovarid = tok->varId();
ovar = tok->variable();
else if (Token::Match(tok, "%var% =|+ 0 )|]|,|;|+"))
ovarid = tok->varId();
if (ovarid) {
const Variable* var = symbolDatabase->getVariableFromVarId(ovarid);
if (var && !var->isPointer() && !var->isArray() && Token::Match(var->typeStartToken(), "std :: string|wstring !!::"))
nullPointerError(tok);
}
ovar = tok->variable();
if (ovar && !ovar->isPointer() && !ovar->isArray() && Token::Match(ovar->typeStartToken(), "std :: string|wstring !!::"))
nullPointerError(tok);
}
}
}
@ -1217,7 +1208,7 @@ void CheckNullPointer::nullPointerDefaultArgument()
for (const Token *tok = scope->function->arg; tok != scope->function->arg->link(); tok = tok->next()) {
if (Token::Match(tok, "%var% = 0 ,|)") && tok->varId() != 0) {
const Variable* var = symbolDatabase->getVariableFromVarId(tok->varId());
const Variable *var = tok->variable();
if (var && var->isPointer())
pointerArgs.insert(tok->varId());
}
@ -1349,7 +1340,7 @@ private:
const Token *parse(const Token &tok, std::list<ExecutionPath *> &checks) const {
if (tok.varId() != 0) {
// Pointer declaration declaration?
const Variable* var = symbolDatabase->getVariableFromVarId(tok.varId());
const Variable *var = tok.variable();
if (var && var->isPointer() && var->nameToken() == &tok)
checks.push_back(new Nullpointer(owner, var->varId(), var->name(), symbolDatabase));
}

View File

@ -46,7 +46,7 @@ void CheckOther::checkIncrementBoolean()
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
if (Token::Match(tok, "%var% ++")) {
if (tok->varId()) {
const Variable *var = symbolDatabase->getVariableFromVarId(tok->varId());
const Variable *var = tok->variable();
if (var && var->typeEndToken()->str() == "bool")
incrementBooleanError(tok);
@ -313,13 +313,13 @@ void CheckOther::checkBitwiseOnBoolean()
const Scope * scope = symbolDatabase->functionScopes[i];
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
if (Token::Match(tok, "(|.|return|&&|%oror%|throw|, %var% [&|]")) {
const Variable *var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(tok->next()->varId());
const Variable *var = tok->next()->variable();
if (var && var->typeEndToken()->str() == "bool") {
bitwiseOnBooleanError(tok->next(), var->name(), tok->strAt(2) == "&" ? "&&" : "||");
tok = tok->tokAt(2);
}
} else if (Token::Match(tok, "[&|] %var% )|.|return|&&|%oror%|throw|,") && (!tok->previous() || !tok->previous()->isExtendedOp() || tok->strAt(-1) == ")")) {
const Variable *var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(tok->next()->varId());
const Variable *var = tok->next()->variable();
if (var && var->typeEndToken()->str() == "bool") {
bitwiseOnBooleanError(tok->next(), var->name(), tok->str() == "&" ? "&&" : "||");
tok = tok->tokAt(2);
@ -448,15 +448,15 @@ void CheckOther::invalidPointerCast()
continue;
// Find casted variable
unsigned int varid = 0;
const Variable *var = 0;
bool allocation = false;
bool ref = false;
if (Token::Match(nextTok, "new %type%"))
allocation = true;
else if (Token::Match(nextTok, "%var% !!["))
varid = nextTok->varId();
var = nextTok->variable();
else if (Token::Match(nextTok, "& %var%") && !Token::Match(nextTok->tokAt(2), "(|[")) {
varid = nextTok->next()->varId();
var = nextTok->next()->variable();
ref = true;
}
@ -465,7 +465,6 @@ void CheckOther::invalidPointerCast()
if (allocation) {
fromTok = nextTok->next();
} else {
const Variable* var = symbolDatabase->getVariableFromVarId(varid);
if (!var || (!ref && !var->isPointer() && !var->isArray()) || (ref && (var->isPointer() || var->isArray())))
continue;
fromTok = var->typeStartToken();
@ -540,7 +539,7 @@ void CheckOther::checkSizeofForArrayParameter()
varTok = varTok->next();
}
if (varTok->varId() > 0) {
const Variable *var = symbolDatabase->getVariableFromVarId(varTok->varId());
const Variable *var = varTok->variable();
if (var && var->isArray() && var->isArgument()) {
sizeofForArrayParameterError(tok);
}
@ -613,13 +612,13 @@ void CheckOther::checkSizeofForPointerSize()
// Ensure the variables are in the symbol database
// Also ensure the variables are pointers
// Only keep variables which are pointers
const Variable *var = symbolDatabase->getVariableFromVarId(variable->varId());
const Variable *var = variable->variable();
if (!var || !var->isPointer() || var->isArray()) {
variable = 0;
}
if (variable2) {
var = symbolDatabase->getVariableFromVarId(variable2->varId());
var = variable2->variable();
if (!var || !var->isPointer() || var->isArray()) {
variable2 = 0;
}
@ -1187,13 +1186,11 @@ void CheckOther::checkSelfAssignment()
if (!_settings->isEnabled("style"))
return;
const SymbolDatabase* symbolDatabase = _tokenizer->getSymbolDatabase();
const Token *tok = findSelfAssignPattern(_tokenizer->tokens());
while (tok) {
if (Token::Match(tok->previous(), "[;{}.]") &&
tok->varId() && tok->varId() == tok->tokAt(2)->varId() &&
isTypeWithoutSideEffects(_tokenizer, symbolDatabase->getVariableFromVarId(tok->varId()))) {
isTypeWithoutSideEffects(_tokenizer, tok->variable())) {
bool err = true;
// no false positive for 'x = x ? x : 1;'
@ -1659,19 +1656,19 @@ void CheckOther::checkComparisonOfBoolWithInt()
const Token* numTok = right;
if (tok->isNumber() && right->varId()) // num with var
std::swap(varTok, numTok);
if (isBool(symbolDatabase->getVariableFromVarId(varTok->varId())) && // Variable has to be a boolean
if (isBool(varTok->variable()) && // Variable has to be a boolean
((tok->strAt(1) != "==" && tok->strAt(1) != "!=") ||
(MathLib::toLongNumber(numTok->str()) != 0 && MathLib::toLongNumber(numTok->str()) != 1))) { // == 0 and != 0 are allowed, for C also == 1 and != 1
comparisonOfBoolWithIntError(varTok, numTok->str(), tok->strAt(1) == "==" || tok->strAt(1) == "!=");
}
} else if (tok->isBoolean() && right->varId()) { // Comparing boolean constant with variable
if (isNonBoolStdType(symbolDatabase->getVariableFromVarId(right->varId()))) { // Variable has to be of non-boolean standard type
if (isNonBoolStdType(right->variable())) { // Variable has to be of non-boolean standard type
comparisonOfBoolWithIntError(right, tok->str(), false);
} else if (tok->strAt(1) != "==" && tok->strAt(1) != "!=") {
comparisonOfBoolWithInvalidComparator(right, tok->str());
}
} else if (tok->varId() && right->isBoolean()) { // Comparing variable with boolean constant
if (isNonBoolStdType(symbolDatabase->getVariableFromVarId(tok->varId()))) { // Variable has to be of non-boolean standard type
if (isNonBoolStdType(tok->variable())) { // Variable has to be of non-boolean standard type
comparisonOfBoolWithIntError(tok, right->str(), false);
} else if (tok->strAt(1) != "==" && tok->strAt(1) != "!=") {
comparisonOfBoolWithInvalidComparator(right, tok->str());
@ -1681,8 +1678,8 @@ void CheckOther::checkComparisonOfBoolWithInt()
} else if (tok->isBoolean() && right->isNumber()) { // number constant with boolean constant
comparisonOfBoolWithIntError(tok, tok->str(), false);
} else if (tok->varId() && right->varId()) { // Comparing two variables, one of them boolean, one of them integer
const Variable* var1 = symbolDatabase->getVariableFromVarId(right->varId());
const Variable* var2 = symbolDatabase->getVariableFromVarId(tok->varId());
const Variable* var1 = right->variable();
const Variable* var2 = tok->variable();
if (isBool(var1) && isNonBoolStdType(var2)) // Comparing boolean with non-bool standard type
comparisonOfBoolWithIntError(tok, var1->name(), false);
else if (isNonBoolStdType(var1) && isBool(var2)) // Comparing non-bool standard type with boolean
@ -1833,16 +1830,16 @@ void CheckOther::checkUnsignedDivision()
continue;
if (Token::Match(tok->next(), "%var% / %num%")) {
if (tok->strAt(3)[0] == '-' && isUnsigned(symbolDatabase->getVariableFromVarId(tok->next()->varId()))) {
if (tok->strAt(3)[0] == '-' && isUnsigned(tok->next()->variable())) {
udivError(tok->next(), false);
}
} else if (Token::Match(tok->next(), "%num% / %var%")) {
if (tok->strAt(1)[0] == '-' && isUnsigned(symbolDatabase->getVariableFromVarId(tok->tokAt(3)->varId()))) {
if (tok->strAt(1)[0] == '-' && isUnsigned(tok->tokAt(3)->variable())) {
udivError(tok->next(), false);
}
} else if (Token::Match(tok->next(), "%var% / %var%") && _settings->inconclusive && style && !ifTok) {
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 ((isUnsigned(var1) && isSigned(var2)) || (isUnsigned(var2) && isSigned(var1))) {
udivError(tok->next(), true);
}
@ -2108,8 +2105,8 @@ void CheckOther::checkCharVariable()
const Scope * scope = symbolDatabase->functionScopes[i];
for (const Token* tok = scope->classStart; tok != scope->classEnd; tok = tok->next()) {
if ((tok->str() != ".") && Token::Match(tok->next(), "%var% [ %var% ]")) {
const Variable* arrayvar = symbolDatabase->getVariableFromVarId(tok->next()->varId());
const Variable* indexvar = symbolDatabase->getVariableFromVarId(tok->tokAt(3)->varId());
const Variable* arrayvar = tok->next()->variable();
const Variable* indexvar = tok->tokAt(3)->variable();
const MathLib::bigint arraysize = (arrayvar && arrayvar->isArray()) ? arrayvar->dimension(0U) : 0;
if (isSignedChar(indexvar) && arraysize > 0x80)
charArrayIndexError(tok->next());
@ -2117,8 +2114,8 @@ void CheckOther::checkCharVariable()
else if (Token::Match(tok, "[;{}] %var% = %any% [&^|] %any% ;")) {
// is a char variable used in the calculation?
if (!isSignedChar(symbolDatabase->getVariableFromVarId(tok->tokAt(3)->varId())) &&
!isSignedChar(symbolDatabase->getVariableFromVarId(tok->tokAt(5)->varId())))
if (!isSignedChar(tok->tokAt(3)->variable()) &&
!isSignedChar(tok->tokAt(5)->variable()))
continue;
// it's ok with a bitwise and where the other operand is 0xff or less..
@ -2130,13 +2127,13 @@ void CheckOther::checkCharVariable()
}
// is the result stored in a short|int|long?
const Variable *var = symbolDatabase->getVariableFromVarId(tok->next()->varId());
const Variable *var = tok->next()->variable();
if (var && Token::Match(var->typeStartToken(), "short|int|long") && !var->isPointer() && !var->isArray())
charBitOpError(tok->tokAt(4)); // This is an error..
}
else if (Token::Match(tok, "[;{}] %var% = %any% [&^|] ( * %var% ) ;")) {
const Variable* var = symbolDatabase->getVariableFromVarId(tok->tokAt(7)->varId());
const Variable* var = tok->tokAt(7)->variable();
if (!var || !var->isPointer() || var->typeStartToken()->str() != "char" || var->typeStartToken()->isUnsigned())
continue;
// it's ok with a bitwise and where the other operand is 0xff or less..
@ -2144,7 +2141,7 @@ void CheckOther::checkCharVariable()
continue;
// is the result stored in a short|int|long?
var = symbolDatabase->getVariableFromVarId(tok->next()->varId());
var = tok->next()->variable();
if (var && Token::Match(var->typeStartToken(), "short|int|long") && !var->isPointer() && !var->isArray())
charBitOpError(tok->tokAt(4)); // This is an error..
}
@ -2241,8 +2238,7 @@ void CheckOther::strPlusChar()
strPlusCharError(tok->next());
// char variable..
unsigned int varid = tok->tokAt(3)->varId();
if (isChar(symbolDatabase->getVariableFromVarId(varid)))
if (isChar(tok->tokAt(3)->variable()))
strPlusCharError(tok->next());
}
}
@ -2499,13 +2495,13 @@ void CheckOther::checkComparisonOfBoolWithBool()
const Token *first_token = tok->previous();
if (first_token->varId()) {
if (isBool(symbolDatabase->getVariableFromVarId(first_token->varId()))) {
if (isBool(first_token->variable())) {
first_token_bool = true;
}
}
const Token *second_token = tok->next();
if (second_token->varId()) {
if (isBool(symbolDatabase->getVariableFromVarId(second_token->varId()))) {
if (isBool(second_token->variable())) {
second_token_bool = true;
}
}
@ -2911,8 +2907,7 @@ namespace {
const Token *_tok;
};
bool inconclusiveFunctionCall(const SymbolDatabase *symbolDatabase,
const std::list<const Function*> &constFunctions,
bool inconclusiveFunctionCall(const std::list<const Function*> &constFunctions,
const ExpressionTokens &tokens)
{
const Token *start = tokens.start;
@ -2932,7 +2927,7 @@ namespace {
const Variable *v = 0;
if (Token::Match(prev->tokAt(-2), "%var% .")) {
const Token *scope = prev->tokAt(-2);
v = symbolDatabase->getVariableFromVarId(scope->varId());
v = scope->variable();
}
// hard coded list of safe, no-side-effect functions
if (v == 0 && Token::Match(prev, "strcmp|strncmp|strlen|wcscmp|wcsncmp|wcslen|memcmp|strcasecmp|strncasecmp"))
@ -2965,7 +2960,7 @@ namespace {
if (it == _expressions.end()) {
ExpressionTokens exprTokens(_start, end);
exprTokens.inconclusiveFunction = lastInconclusive || inconclusiveFunctionCall(
_symbolDatabase, _constFunctions, exprTokens);
_constFunctions, exprTokens);
_expressions.insert(std::make_pair(e, exprTokens));
_lastTokens = &_expressions.find(e)->second;
} else {
@ -3178,7 +3173,7 @@ void CheckOther::checkDuplicateExpression()
// float == float and float != float are valid NaN checks
// float - float is a valid Inf check
if (Token::Match(tok->tokAt(2), "==|!=|-") && tok->next()->varId()) {
const Variable * var = symbolDatabase->getVariableFromVarId(tok->next()->varId());
const Variable *var = tok->next()->variable();
if (var && var->typeStartToken() == var->typeEndToken()) {
if (Token::Match(var->typeStartToken(), "float|double"))
continue;
@ -3306,7 +3301,7 @@ void CheckOther::checkSuspiciousStringCompare()
if (varTok->type() == Token::eString)
std::swap(varTok, litTok);
const Variable* var = symbolDatabase->getVariableFromVarId(varTok->varId());
const Variable *var = varTok->variable();
if (var) {
if (_tokenizer->isC() ||
(var->isPointer() && varTok->strAt(-1) != "*" && !Token::Match(varTok->next(), "[.([]")))
@ -3408,12 +3403,10 @@ void CheckOther::suspiciousSizeofCalculation()
if (!_settings->isEnabled("style") || !_settings->inconclusive)
return;
const SymbolDatabase* symbolDatabase = _tokenizer->getSymbolDatabase();
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
if (Token::simpleMatch(tok, "sizeof (")) {
const Token* const end = tok->linkAt(1);
const Variable* var = symbolDatabase->getVariableFromVarId(end->previous()->varId());
const Variable* var = end->previous()->variable();
if (end->strAt(-1) == "*" || (var && var->isPointer() && !var->isArray())) {
if (end->strAt(1) == "/")
divideSizeofError(tok);
@ -3447,7 +3440,7 @@ void CheckOther::checkAssignBoolToPointer()
const Scope * scope = symbolDatabase->functionScopes[i];
for (const Token* tok = scope->classStart; tok != scope->classEnd; tok = tok->next()) {
if (Token::Match(tok, "!!* %var% = %bool% ;")) {
const Variable *var1(symbolDatabase->getVariableFromVarId(tok->next()->varId()));
const Variable *var1(tok->next()->variable());
// Is variable a pointer?
if (var1 && var1->isPointer())
@ -3513,7 +3506,7 @@ void CheckOther::checkComparisonOfBoolExpressionWithInt()
if (numTok->isNumber()) {
if (((numTok->str() != "0" && numTok->str() != "1") || !Token::Match(opTok, "!=|==")) && !((op == '<' && numTok->str() == "1") || (op == '>' && numTok->str() == "0")))
comparisonOfBoolExpressionWithIntError(tok, true);
} else if (isNonBoolStdType(symbolDatabase->getVariableFromVarId(numTok->varId())))
} else if (isNonBoolStdType(numTok->variable()))
comparisonOfBoolExpressionWithIntError(tok, false);
}
}
@ -3551,25 +3544,25 @@ void CheckOther::checkSignOfUnsignedVariable()
// check all the code in the function
for (const Token *tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
if (Token::Match(tok, "%var% <|<= 0") && tok->varId() && !Token::Match(tok->previous(), "++|--|)|+|-|*|/|~|<<|>>") && !Token::Match(tok->tokAt(3), "+|-")) {
const Variable * var = symbolDatabase->getVariableFromVarId(tok->varId());
const Variable *var = tok->variable();
if (var && var->typeEndToken()->isUnsigned())
unsignedLessThanZeroError(tok, var->name(), inconclusive);
else if (var && var->isPointer() && tok->strAt(-1) != "*")
pointerLessThanZeroError(tok, inconclusive);
} else if (Token::Match(tok, "0 >|>= %var%") && tok->tokAt(2)->varId() && !Token::Match(tok->tokAt(3), "+|-|*|/") && !Token::Match(tok->previous(), "+|-|<<|>>|~")) {
const Variable * var = symbolDatabase->getVariableFromVarId(tok->tokAt(2)->varId());
const Variable *var = tok->tokAt(2)->variable();
if (var && var->typeEndToken()->isUnsigned())
unsignedLessThanZeroError(tok, var->name(), inconclusive);
else if (var && var->isPointer() && !Token::Match(tok->tokAt(3), "[.[]"))
pointerLessThanZeroError(tok, inconclusive);
} else if (Token::Match(tok, "0 <= %var%") && tok->tokAt(2)->varId() && !Token::Match(tok->tokAt(3), "+|-|*|/") && !Token::Match(tok->previous(), "+|-|<<|>>|~")) {
const Variable * var = symbolDatabase->getVariableFromVarId(tok->tokAt(2)->varId());
const Variable *var = tok->tokAt(2)->variable();
if (var && var->typeEndToken()->isUnsigned())
unsignedPositiveError(tok, var->name(), inconclusive);
else if (var && var->isPointer() && !Token::Match(tok->tokAt(3), "[.[]"))
pointerPositiveError(tok, inconclusive);
} else if (Token::Match(tok, "%var% >= 0") && tok->varId() && !Token::Match(tok->previous(), "++|--|)|+|-|*|/|~|<<|>>") && !Token::Match(tok->tokAt(3), "+|-")) {
const Variable * var = symbolDatabase->getVariableFromVarId(tok->varId());
const Variable *var = tok->variable();
if (var && var->typeEndToken()->isUnsigned())
unsignedPositiveError(tok, var->name(), inconclusive);
else if (var && var->isPointer() && tok->strAt(-1) != "*")
@ -3687,7 +3680,7 @@ void CheckOther::checkNegativeBitwiseShift()
if ((Token::Match(tok,"%var% >>|<< %num%") || Token::Match(tok,"%num% >>|<< %num%")) && !Token::Match(tok->previous(),">>|<<")) {
if (tok->isName()) {
const Variable* var = symbolDatabase->getVariableFromVarId(tok->varId());
const Variable *var = tok->variable();
if (var && var->typeStartToken()->isStandardType() && (tok->strAt(2))[0] == '-')
negativeBitwiseShiftError(tok);
} else {
@ -3721,7 +3714,7 @@ void CheckOther::checkIncompleteArrayFill()
const Scope * scope = symbolDatabase->functionScopes[i];
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
if (Token::Match(tok, "memset|memcpy|memmove ( %var% ,") && Token::Match(tok->linkAt(1)->tokAt(-2), ", %num% )")) {
const Variable* var = symbolDatabase->getVariableFromVarId(tok->tokAt(2)->varId());
const Variable *var = tok->tokAt(2)->variable();
if (!var || !var->isArray() || var->dimensions().empty() || !var->dimension(0))
continue;

View File

@ -775,7 +775,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const
if (Token::Match(tok->previous(), "[;{}]")) {
for (const Token* tok2 = tok->next(); tok2; tok2 = tok2->next()) {
if (tok2->varId()) {
const Variable* var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(tok2->varId());
const Variable *var = tok2->variable();
if (var && var->nameToken() == tok2) { // Declaration: Skip
tok = tok2->next();
if (Token::Match(tok, "( %var% )")) // Simple initialization through copy ctor
@ -889,7 +889,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const
// is it a user defined type?
if (!type->isStandardType()) {
const Variable* variable = _tokenizer->getSymbolDatabase()->getVariableFromVarId(start->varId());
const Variable *variable = start->variable();
if (!variable || !isRecordTypeWithoutSideEffects(variable->type()))
allocate = false;
}
@ -1176,7 +1176,7 @@ void CheckUnusedVar::checkStructMemberUsage()
tok2 && tok2->next();
tok2 = Token::findmatch(tok2->next(), (structname + " %var%").c_str())) {
const Variable *var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(tok2->next()->varId());
const Variable *var = tok2->next()->variable();
if (var && (var->isExtern() || (var->isGlobal() && !var->isStatic()))) {
structname.clear();
break;