Fixed #4535 (Simplify checks by caching symbol database Variable pointer in Token)
This commit is contained in:
parent
d9de7f7052
commit
42588e9729
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue