use nonneg int for varid and exprid (#3085)

This commit is contained in:
IOBYTE 2021-01-27 13:49:13 -05:00 committed by GitHub
parent 0bd137dc11
commit 4e1ff86bb2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 131 additions and 127 deletions

View File

@ -81,7 +81,7 @@ const Token* findAstNode(const Token* ast, const std::function<bool(const Token*
return result; return result;
} }
const Token* findExpression(MathLib::bigint exprid, const Token* findExpression(const nonneg int exprid,
const Token* start, const Token* start,
const Token* end, const Token* end,
const std::function<bool(const Token*)>& pred) const std::function<bool(const Token*)>& pred)
@ -2257,13 +2257,13 @@ static bool hasFunctionCall(const Token *tok)
return hasFunctionCall(tok->astOperand1()) || hasFunctionCall(tok->astOperand2()); return hasFunctionCall(tok->astOperand1()) || hasFunctionCall(tok->astOperand2());
} }
static bool isUnchanged(const Token *startToken, const Token *endToken, const std::set<int> &exprVarIds, bool local) static bool isUnchanged(const Token *startToken, const Token *endToken, const std::set<nonneg int> &exprVarIds, bool local)
{ {
for (const Token *tok = startToken; tok != endToken; tok = tok->next()) { for (const Token *tok = startToken; tok != endToken; tok = tok->next()) {
if (!local && Token::Match(tok, "%name% (") && !Token::simpleMatch(tok->linkAt(1), ") {")) if (!local && Token::Match(tok, "%name% (") && !Token::simpleMatch(tok->linkAt(1), ") {"))
// TODO: this is a quick bailout // TODO: this is a quick bailout
return false; return false;
if (tok->varId() <= 0 || exprVarIds.find(tok->varId()) == exprVarIds.end()) if (tok->varId() == 0 || exprVarIds.find(tok->varId()) == exprVarIds.end())
continue; continue;
const Token *parent = tok; const Token *parent = tok;
while (parent->astParent() && !parent->astParent()->isAssignmentOp() && parent->astParent()->tokType() != Token::Type::eIncDecOp) { while (parent->astParent() && !parent->astParent()->isAssignmentOp() && parent->astParent()->tokType() != Token::Type::eIncDecOp) {
@ -2364,7 +2364,7 @@ bool isGlobalData(const Token *expr, bool cpp)
return globalData; return globalData;
} }
struct FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const Token *startToken, const Token *endToken, const std::set<int> &exprVarIds, bool local, bool inInnerClass, int depth) struct FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const Token *startToken, const Token *endToken, const std::set<nonneg int> &exprVarIds, bool local, bool inInnerClass, int depth)
{ {
// Parse the given tokens // Parse the given tokens
if (++depth > 1000) if (++depth > 1000)
@ -2650,10 +2650,10 @@ bool FwdAnalysis::isGlobalData(const Token *expr) const
return ::isGlobalData(expr, mCpp); return ::isGlobalData(expr, mCpp);
} }
std::set<int> FwdAnalysis::getExprVarIds(const Token* expr, bool* localOut, bool* unknownVarIdOut) const std::set<nonneg int> FwdAnalysis::getExprVarIds(const Token* expr, bool* localOut, bool* unknownVarIdOut) const
{ {
// all variable ids in expr. // all variable ids in expr.
std::set<int> exprVarIds; std::set<nonneg int> exprVarIds;
bool local = true; bool local = true;
bool unknownVarId = false; bool unknownVarId = false;
visitAstNodes(expr, visitAstNodes(expr,
@ -2687,7 +2687,7 @@ FwdAnalysis::Result FwdAnalysis::check(const Token* expr, const Token* startToke
// all variable ids in expr. // all variable ids in expr.
bool local = true; bool local = true;
bool unknownVarId = false; bool unknownVarId = false;
std::set<int> exprVarIds = getExprVarIds(expr, &local, &unknownVarId); std::set<nonneg int> exprVarIds = getExprVarIds(expr, &local, &unknownVarId);
if (unknownVarId) if (unknownVarId)
return Result(FwdAnalysis::Result::Type::BAILOUT); return Result(FwdAnalysis::Result::Type::BAILOUT);

View File

@ -53,7 +53,7 @@ void visitAstNodes(const Token *ast, std::function<ChildrenToVisit(const Token *
void visitAstNodes(Token *ast, std::function<ChildrenToVisit(Token *)> visitor); void visitAstNodes(Token *ast, std::function<ChildrenToVisit(Token *)> visitor);
const Token* findAstNode(const Token* ast, const std::function<bool(const Token*)>& pred); const Token* findAstNode(const Token* ast, const std::function<bool(const Token*)>& pred);
const Token* findExpression(MathLib::bigint exprid, const Token* findExpression(const nonneg int exprid,
const Token* start, const Token* start,
const Token* end, const Token* end,
const std::function<bool(const Token*)>& pred); const std::function<bool(const Token*)>& pred);
@ -319,7 +319,7 @@ public:
/** Is there some possible alias for given expression */ /** Is there some possible alias for given expression */
bool possiblyAliased(const Token *expr, const Token *startToken) const; bool possiblyAliased(const Token *expr, const Token *startToken) const;
std::set<int> getExprVarIds(const Token* expr, bool* localOut = nullptr, bool* unknownVarIdOut = nullptr) const; std::set<nonneg int> getExprVarIds(const Token* expr, bool* localOut = nullptr, bool* unknownVarIdOut = nullptr) const;
private: private:
static bool isEscapedAlias(const Token* expr); static bool isEscapedAlias(const Token* expr);
@ -332,7 +332,7 @@ private:
}; };
struct Result check(const Token *expr, const Token *startToken, const Token *endToken); struct Result check(const Token *expr, const Token *startToken, const Token *endToken);
struct Result checkRecursive(const Token *expr, const Token *startToken, const Token *endToken, const std::set<int> &exprVarIds, bool local, bool inInnerClass, int depth=0); struct Result checkRecursive(const Token *expr, const Token *startToken, const Token *endToken, const std::set<nonneg int> &exprVarIds, bool local, bool inInnerClass, int depth=0);
// Is expression a l-value global data? // Is expression a l-value global data?
bool isGlobalData(const Token *expr) const; bool isGlobalData(const Token *expr) const;

View File

@ -147,7 +147,7 @@ void CheckUninitVar::checkScope(const Scope* scope, const std::set<std::string>
if (var.isArray()) { if (var.isArray()) {
Alloc alloc = ARRAY; Alloc alloc = ARRAY;
const std::map<int, VariableValue> variableValue; const std::map<nonneg int, VariableValue> variableValue;
bool init = false; bool init = false;
for (const Token *parent = var.nameToken(); parent; parent = parent->astParent()) { for (const Token *parent = var.nameToken(); parent; parent = parent->astParent()) {
if (parent->str() == "=") { if (parent->str() == "=") {
@ -161,7 +161,7 @@ void CheckUninitVar::checkScope(const Scope* scope, const std::set<std::string>
} }
if (stdtype || var.isPointer()) { if (stdtype || var.isPointer()) {
Alloc alloc = NO_ALLOC; Alloc alloc = NO_ALLOC;
const std::map<int, VariableValue> variableValue; const std::map<nonneg int, VariableValue> variableValue;
checkScopeForVariable(tok, var, nullptr, nullptr, &alloc, emptyString, variableValue); checkScopeForVariable(tok, var, nullptr, nullptr, &alloc, emptyString, variableValue);
} }
if (var.type()) if (var.type())
@ -183,7 +183,7 @@ void CheckUninitVar::checkScope(const Scope* scope, const std::set<std::string>
checkStruct(tok, arg); checkStruct(tok, arg);
else if (arg.typeStartToken()->isStandardType() || arg.typeStartToken()->isEnumType()) { else if (arg.typeStartToken()->isStandardType() || arg.typeStartToken()->isEnumType()) {
Alloc alloc = NO_ALLOC; Alloc alloc = NO_ALLOC;
const std::map<int, VariableValue> variableValue; const std::map<nonneg int, VariableValue> variableValue;
checkScopeForVariable(tok->next(), arg, nullptr, nullptr, &alloc, emptyString, variableValue); checkScopeForVariable(tok->next(), arg, nullptr, nullptr, &alloc, emptyString, variableValue);
} }
} }
@ -220,7 +220,7 @@ void CheckUninitVar::checkStruct(const Token *tok, const Variable &structvar)
const Token *tok2 = tok; const Token *tok2 = tok;
if (tok->str() == "}") if (tok->str() == "}")
tok2 = tok2->next(); tok2 = tok2->next();
const std::map<int, VariableValue> variableValue; const std::map<nonneg int, VariableValue> variableValue;
checkScopeForVariable(tok2, structvar, nullptr, nullptr, &alloc, var.name(), variableValue); checkScopeForVariable(tok2, structvar, nullptr, nullptr, &alloc, var.name(), variableValue);
} }
} }
@ -242,7 +242,7 @@ static bool operator!=(const VariableValue & v, MathLib::bigint i)
return v.notEqual ? (i == v.value) : (i != v.value); return v.notEqual ? (i == v.value) : (i != v.value);
} }
static void conditionAlwaysTrueOrFalse(const Token *tok, const std::map<int, VariableValue> &variableValue, bool *alwaysTrue, bool *alwaysFalse) static void conditionAlwaysTrueOrFalse(const Token *tok, const std::map<nonneg int, VariableValue> &variableValue, bool *alwaysTrue, bool *alwaysFalse)
{ {
if (!tok) if (!tok)
return; return;
@ -258,7 +258,7 @@ static void conditionAlwaysTrueOrFalse(const Token *tok, const std::map<int, Var
if (tok->isName() || tok->str() == ".") { if (tok->isName() || tok->str() == ".") {
while (tok && tok->str() == ".") while (tok && tok->str() == ".")
tok = tok->astOperand2(); tok = tok->astOperand2();
const std::map<int, VariableValue>::const_iterator it = variableValue.find(tok ? tok->varId() : ~0U); const std::map<nonneg int, VariableValue>::const_iterator it = variableValue.find(tok ? tok->varId() : ~0U);
if (it != variableValue.end()) { if (it != variableValue.end()) {
*alwaysTrue = (it->second != 0LL); *alwaysTrue = (it->second != 0LL);
*alwaysFalse = (it->second == 0LL); *alwaysFalse = (it->second == 0LL);
@ -284,7 +284,7 @@ static void conditionAlwaysTrueOrFalse(const Token *tok, const std::map<int, Var
while (vartok && vartok->str() == ".") while (vartok && vartok->str() == ".")
vartok = vartok->astOperand2(); vartok = vartok->astOperand2();
const std::map<int, VariableValue>::const_iterator it = variableValue.find(vartok ? vartok->varId() : ~0U); const std::map<nonneg int, VariableValue>::const_iterator it = variableValue.find(vartok ? vartok->varId() : ~0U);
if (it == variableValue.end()) if (it == variableValue.end())
return; return;
@ -351,7 +351,7 @@ static bool isVariableUsed(const Token *tok, const Variable& var)
return !parent2 || parent2->isConstOp() || (parent2->str() == "=" && parent2->astOperand2() == parent); return !parent2 || parent2->isConstOp() || (parent2->str() == "=" && parent2->astOperand2() == parent);
} }
bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var, bool * const possibleInit, bool * const noreturn, Alloc* const alloc, const std::string &membervar, std::map<int, VariableValue> variableValue) bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var, bool * const possibleInit, bool * const noreturn, Alloc* const alloc, const std::string &membervar, std::map<nonneg int, VariableValue> variableValue)
{ {
const bool suppressErrors(possibleInit && *possibleInit); // Assume that this is a variable delaratkon, rather than a fundef const bool suppressErrors(possibleInit && *possibleInit); // Assume that this is a variable delaratkon, rather than a fundef
const bool printDebug = mSettings->debugwarnings; const bool printDebug = mSettings->debugwarnings;
@ -412,14 +412,14 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var
return true; return true;
// checking if a not-zero variable is zero => bail out // checking if a not-zero variable is zero => bail out
int condVarId = 0; nonneg int condVarId = 0;
VariableValue condVarValue(0); VariableValue condVarValue(0);
const Token *condVarTok = nullptr; const Token *condVarTok = nullptr;
if (alwaysFalse) if (alwaysFalse)
; ;
else if (Token::simpleMatch(tok, "if (") && else if (Token::simpleMatch(tok, "if (") &&
astIsVariableComparison(tok->next()->astOperand2(), "!=", "0", &condVarTok)) { astIsVariableComparison(tok->next()->astOperand2(), "!=", "0", &condVarTok)) {
const std::map<int,VariableValue>::const_iterator it = variableValue.find(condVarTok->varId()); const std::map<nonneg int,VariableValue>::const_iterator it = variableValue.find(condVarTok->varId());
if (it != variableValue.end() && it->second != 0) if (it != variableValue.end() && it->second != 0)
return true; // this scope is not fully analysed => return true return true; // this scope is not fully analysed => return true
else { else {
@ -435,7 +435,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var
while (Token::simpleMatch(vartok, ".")) while (Token::simpleMatch(vartok, "."))
vartok = vartok->astOperand2(); vartok = vartok->astOperand2();
if (vartok && vartok->varId() && numtok && numtok->hasKnownIntValue()) { if (vartok && vartok->varId() && numtok && numtok->hasKnownIntValue()) {
const std::map<int,VariableValue>::const_iterator it = variableValue.find(vartok->varId()); const std::map<nonneg int,VariableValue>::const_iterator it = variableValue.find(vartok->varId());
if (it != variableValue.end() && it->second != numtok->getKnownIntValue()) if (it != variableValue.end() && it->second != numtok->getKnownIntValue())
return true; // this scope is not fully analysed => return true return true; // this scope is not fully analysed => return true
condVarId = vartok->varId(); condVarId = vartok->varId();
@ -475,7 +475,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var
if (alwaysTrue && (initif || noreturnIf)) if (alwaysTrue && (initif || noreturnIf))
return true; return true;
std::map<int, VariableValue> varValueIf; std::map<nonneg int, VariableValue> varValueIf;
if (!alwaysFalse && !initif && !noreturnIf) { if (!alwaysFalse && !initif && !noreturnIf) {
for (const Token *tok2 = tok; tok2 && tok2 != tok->link(); tok2 = tok2->next()) { for (const Token *tok2 = tok; tok2 && tok2 != tok->link(); tok2 = tok2->next()) {
if (Token::Match(tok2, "[;{}.] %name% = - %name% ;")) if (Token::Match(tok2, "[;{}.] %name% = - %name% ;"))
@ -485,7 +485,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var
} }
} }
if (initif && condVarId > 0U) if (initif && condVarId > 0)
variableValue[condVarId] = !condVarValue; variableValue[condVarId] = !condVarValue;
// goto the } // goto the }
@ -505,7 +505,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var
bool noreturnElse = false; bool noreturnElse = false;
const bool initelse = !alwaysTrue && checkScopeForVariable(tok->next(), var, &possibleInitElse, &noreturnElse, alloc, membervar, variableValue); const bool initelse = !alwaysTrue && checkScopeForVariable(tok->next(), var, &possibleInitElse, &noreturnElse, alloc, membervar, variableValue);
std::map<int, VariableValue> varValueElse; std::map<nonneg int, VariableValue> varValueElse;
if (!alwaysTrue && !initelse && !noreturnElse) { if (!alwaysTrue && !initelse && !noreturnElse) {
for (const Token *tok2 = tok; tok2 && tok2 != tok->link(); tok2 = tok2->next()) { for (const Token *tok2 = tok; tok2 && tok2 != tok->link(); tok2 = tok2->next()) {
if (Token::Match(tok2, "[;{}.] %var% = - %name% ;")) if (Token::Match(tok2, "[;{}.] %var% = - %name% ;"))
@ -515,7 +515,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var
} }
} }
if (initelse && condVarId > 0U && !noreturnIf && !noreturnElse) if (initelse && condVarId > 0 && !noreturnIf && !noreturnElse)
variableValue[condVarId] = condVarValue; variableValue[condVarId] = condVarValue;
// goto the } // goto the }

View File

@ -78,7 +78,7 @@ public:
void checkScope(const Scope* scope, const std::set<std::string> &arrayTypeDefs); void checkScope(const Scope* scope, const std::set<std::string> &arrayTypeDefs);
void checkStruct(const Token *tok, const Variable &structvar); void checkStruct(const Token *tok, const Variable &structvar);
enum Alloc { NO_ALLOC, NO_CTOR_CALL, CTOR_CALL, ARRAY }; enum Alloc { NO_ALLOC, NO_CTOR_CALL, CTOR_CALL, ARRAY };
bool checkScopeForVariable(const Token *tok, const Variable& var, bool* const possibleInit, bool* const noreturn, Alloc* const alloc, const std::string &membervar, std::map<int, VariableValue> variableValue); bool checkScopeForVariable(const Token *tok, const Variable& var, bool* const possibleInit, bool* const noreturn, Alloc* const alloc, const std::string &membervar, std::map<nonneg int, VariableValue> variableValue);
bool checkIfForWhileHead(const Token *startparentheses, const Variable& var, bool suppressErrors, bool isuninit, Alloc alloc, const std::string &membervar); bool checkIfForWhileHead(const Token *startparentheses, const Variable& var, bool suppressErrors, bool isuninit, Alloc alloc, const std::string &membervar);
bool checkLoopBody(const Token *tok, const Variable& var, const Alloc alloc, const std::string &membervar, const bool suppressErrors); bool checkLoopBody(const Token *tok, const Variable& var, const Alloc alloc, const std::string &membervar, const bool suppressErrors);
void checkRhs(const Token *tok, const Variable &var, Alloc alloc, nonneg int number_of_if, const std::string &membervar); void checkRhs(const Token *tok, const Variable &var, Alloc alloc, nonneg int number_of_if, const std::string &membervar);

View File

@ -129,7 +129,7 @@ public:
return (!_read && !_write); return (!_read && !_write);
} }
std::set<unsigned int> _aliases; std::set<nonneg int> _aliases;
std::set<const Scope*> _assignments; std::set<const Scope*> _assignments;
const Variable* _var; const Variable* _var;
@ -144,31 +144,31 @@ public:
void clear() { void clear() {
mVarUsage.clear(); mVarUsage.clear();
} }
const std::map<unsigned int, VariableUsage> &varUsage() const { const std::map<nonneg int, VariableUsage> &varUsage() const {
return mVarUsage; return mVarUsage;
} }
void addVar(const Variable *var, VariableType type, bool write_); void addVar(const Variable *var, VariableType type, bool write_);
void allocateMemory(unsigned int varid, const Token* tok); void allocateMemory(nonneg int varid, const Token* tok);
void read(unsigned int varid, const Token* tok); void read(nonneg int varid, const Token* tok);
void readAliases(unsigned int varid, const Token* tok); void readAliases(nonneg int varid, const Token* tok);
void readAll(unsigned int varid, const Token* tok); void readAll(nonneg int varid, const Token* tok);
void write(unsigned int varid, const Token* tok); void write(nonneg int varid, const Token* tok);
void writeAliases(unsigned int varid, const Token* tok); void writeAliases(nonneg int varid, const Token* tok);
void writeAll(unsigned int varid, const Token* tok); void writeAll(nonneg int varid, const Token* tok);
void use(unsigned int varid, const Token* tok); void use(nonneg int varid, const Token* tok);
void modified(unsigned int varid, const Token* tok); void modified(nonneg int varid, const Token* tok);
VariableUsage *find(unsigned int varid); VariableUsage *find(nonneg int varid);
void alias(unsigned int varid1, unsigned int varid2, bool replace); void alias(nonneg int varid1, nonneg int varid2, bool replace);
void erase(unsigned int varid) { void erase(nonneg int varid) {
mVarUsage.erase(varid); mVarUsage.erase(varid);
} }
void eraseAliases(unsigned int varid); void eraseAliases(nonneg int varid);
void eraseAll(unsigned int varid); void eraseAll(nonneg int varid);
void clearAliases(unsigned int varid); void clearAliases(nonneg int varid);
private: private:
std::map<unsigned int, VariableUsage> mVarUsage; std::map<nonneg int, VariableUsage> mVarUsage;
}; };
@ -179,7 +179,7 @@ private:
* merge the aliases when this assignment is in a different scope from the * merge the aliases when this assignment is in a different scope from the
* previous assignment depending on the relationship of the 2 scopes. * previous assignment depending on the relationship of the 2 scopes.
*/ */
void Variables::alias(unsigned int varid1, unsigned int varid2, bool replace) void Variables::alias(nonneg int varid1, nonneg int varid2, bool replace)
{ {
VariableUsage *var1 = find(varid1); VariableUsage *var1 = find(varid1);
VariableUsage *var2 = find(varid2); VariableUsage *var2 = find(varid2);
@ -195,7 +195,7 @@ void Variables::alias(unsigned int varid1, unsigned int varid2, bool replace)
if (replace) { if (replace) {
// remove var1 from all aliases // remove var1 from all aliases
for (std::set<unsigned int>::const_iterator i = var1->_aliases.begin(); i != var1->_aliases.end(); ++i) { for (std::set<nonneg int>::const_iterator i = var1->_aliases.begin(); i != var1->_aliases.end(); ++i) {
VariableUsage *temp = find(*i); VariableUsage *temp = find(*i);
if (temp) if (temp)
@ -207,7 +207,7 @@ void Variables::alias(unsigned int varid1, unsigned int varid2, bool replace)
} }
// var1 gets all var2s aliases // var1 gets all var2s aliases
for (std::set<unsigned int>::const_iterator i = var2->_aliases.begin(); i != var2->_aliases.end(); ++i) { for (std::set<nonneg int>::const_iterator i = var2->_aliases.begin(); i != var2->_aliases.end(); ++i) {
if (*i != varid1) if (*i != varid1)
var1->_aliases.insert(*i); var1->_aliases.insert(*i);
} }
@ -221,13 +221,13 @@ void Variables::alias(unsigned int varid1, unsigned int varid2, bool replace)
} }
} }
void Variables::clearAliases(unsigned int varid) void Variables::clearAliases(nonneg int varid)
{ {
VariableUsage *usage = find(varid); VariableUsage *usage = find(varid);
if (usage) { if (usage) {
// remove usage from all aliases // remove usage from all aliases
std::set<unsigned int>::const_iterator i; std::set<nonneg int>::const_iterator i;
for (i = usage->_aliases.begin(); i != usage->_aliases.end(); ++i) { for (i = usage->_aliases.begin(); i != usage->_aliases.end(); ++i) {
VariableUsage *temp = find(*i); VariableUsage *temp = find(*i);
@ -241,17 +241,17 @@ void Variables::clearAliases(unsigned int varid)
} }
} }
void Variables::eraseAliases(unsigned int varid) void Variables::eraseAliases(nonneg int varid)
{ {
VariableUsage *usage = find(varid); VariableUsage *usage = find(varid);
if (usage) { if (usage) {
for (std::set<unsigned int>::const_iterator aliases = usage->_aliases.begin(); aliases != usage->_aliases.end(); ++aliases) for (std::set<nonneg int>::const_iterator aliases = usage->_aliases.begin(); aliases != usage->_aliases.end(); ++aliases)
erase(*aliases); erase(*aliases);
} }
} }
void Variables::eraseAll(unsigned int varid) void Variables::eraseAll(nonneg int varid)
{ {
eraseAliases(varid); eraseAliases(varid);
erase(varid); erase(varid);
@ -266,7 +266,7 @@ void Variables::addVar(const Variable *var,
} }
} }
void Variables::allocateMemory(unsigned int varid, const Token* tok) void Variables::allocateMemory(nonneg int varid, const Token* tok)
{ {
VariableUsage *usage = find(varid); VariableUsage *usage = find(varid);
@ -276,7 +276,7 @@ void Variables::allocateMemory(unsigned int varid, const Token* tok)
} }
} }
void Variables::read(unsigned int varid, const Token* tok) void Variables::read(nonneg int varid, const Token* tok)
{ {
VariableUsage *usage = find(varid); VariableUsage *usage = find(varid);
@ -287,12 +287,12 @@ void Variables::read(unsigned int varid, const Token* tok)
} }
} }
void Variables::readAliases(unsigned int varid, const Token* tok) void Variables::readAliases(nonneg int varid, const Token* tok)
{ {
VariableUsage *usage = find(varid); VariableUsage *usage = find(varid);
if (usage) { if (usage) {
for (unsigned int aliases : usage->_aliases) { for (nonneg int aliases : usage->_aliases) {
VariableUsage *aliased = find(aliases); VariableUsage *aliased = find(aliases);
if (aliased) { if (aliased) {
@ -303,13 +303,13 @@ void Variables::readAliases(unsigned int varid, const Token* tok)
} }
} }
void Variables::readAll(unsigned int varid, const Token* tok) void Variables::readAll(nonneg int varid, const Token* tok)
{ {
read(varid, tok); read(varid, tok);
readAliases(varid, tok); readAliases(varid, tok);
} }
void Variables::write(unsigned int varid, const Token* tok) void Variables::write(nonneg int varid, const Token* tok)
{ {
VariableUsage *usage = find(varid); VariableUsage *usage = find(varid);
@ -321,12 +321,12 @@ void Variables::write(unsigned int varid, const Token* tok)
} }
} }
void Variables::writeAliases(unsigned int varid, const Token* tok) void Variables::writeAliases(nonneg int varid, const Token* tok)
{ {
VariableUsage *usage = find(varid); VariableUsage *usage = find(varid);
if (usage) { if (usage) {
for (std::set<unsigned int>::const_iterator aliases = usage->_aliases.begin(); aliases != usage->_aliases.end(); ++aliases) { for (std::set<nonneg int>::const_iterator aliases = usage->_aliases.begin(); aliases != usage->_aliases.end(); ++aliases) {
VariableUsage *aliased = find(*aliases); VariableUsage *aliased = find(*aliases);
if (aliased) { if (aliased) {
@ -337,13 +337,13 @@ void Variables::writeAliases(unsigned int varid, const Token* tok)
} }
} }
void Variables::writeAll(unsigned int varid, const Token* tok) void Variables::writeAll(nonneg int varid, const Token* tok)
{ {
write(varid, tok); write(varid, tok);
writeAliases(varid, tok); writeAliases(varid, tok);
} }
void Variables::use(unsigned int varid, const Token* tok) void Variables::use(nonneg int varid, const Token* tok)
{ {
VariableUsage *usage = find(varid); VariableUsage *usage = find(varid);
@ -351,7 +351,7 @@ void Variables::use(unsigned int varid, const Token* tok)
usage->use(); usage->use();
usage->_lastAccess = tok; usage->_lastAccess = tok;
for (std::set<unsigned int>::const_iterator aliases = usage->_aliases.begin(); aliases != usage->_aliases.end(); ++aliases) { for (std::set<nonneg int>::const_iterator aliases = usage->_aliases.begin(); aliases != usage->_aliases.end(); ++aliases) {
VariableUsage *aliased = find(*aliases); VariableUsage *aliased = find(*aliases);
if (aliased) { if (aliased) {
@ -362,7 +362,7 @@ void Variables::use(unsigned int varid, const Token* tok)
} }
} }
void Variables::modified(unsigned int varid, const Token* tok) void Variables::modified(nonneg int varid, const Token* tok)
{ {
VariableUsage *usage = find(varid); VariableUsage *usage = find(varid);
@ -372,7 +372,7 @@ void Variables::modified(unsigned int varid, const Token* tok)
usage->_modified = true; usage->_modified = true;
usage->_lastAccess = tok; usage->_lastAccess = tok;
for (std::set<unsigned int>::const_iterator aliases = usage->_aliases.begin(); aliases != usage->_aliases.end(); ++aliases) { for (std::set<nonneg int>::const_iterator aliases = usage->_aliases.begin(); aliases != usage->_aliases.end(); ++aliases) {
VariableUsage *aliased = find(*aliases); VariableUsage *aliased = find(*aliases);
if (aliased) { if (aliased) {
@ -383,10 +383,10 @@ void Variables::modified(unsigned int varid, const Token* tok)
} }
} }
Variables::VariableUsage *Variables::find(unsigned int varid) Variables::VariableUsage *Variables::find(nonneg int varid)
{ {
if (varid) { if (varid) {
std::map<unsigned int, VariableUsage>::iterator i = mVarUsage.find(varid); std::map<nonneg int, VariableUsage>::iterator i = mVarUsage.find(varid);
if (i != mVarUsage.end()) if (i != mVarUsage.end())
return &i->second; return &i->second;
} }
@ -409,7 +409,7 @@ static const Token* doAssignment(Variables &variables, const Token *tok, bool de
const Token* const tokOld = tok; const Token* const tokOld = tok;
// check for aliased variable // check for aliased variable
const unsigned int varid1 = tok->varId(); const nonneg int varid1 = tok->varId();
Variables::VariableUsage *var1 = variables.find(varid1); Variables::VariableUsage *var1 = variables.find(varid1);
if (var1) { if (var1) {
@ -494,7 +494,7 @@ static const Token* doAssignment(Variables &variables, const Token *tok, bool de
} }
// check if variable is local // check if variable is local
const unsigned int varid2 = tok->varId(); const nonneg int varid2 = tok->varId();
const Variables::VariableUsage* var2 = variables.find(varid2); const Variables::VariableUsage* var2 = variables.find(varid2);
if (var2) { // local variable (alias or read it) if (var2) { // local variable (alias or read it)
@ -599,7 +599,7 @@ static const Token* doAssignment(Variables &variables, const Token *tok, bool de
else if (Token::Match(tok->tokAt(-2), "%name% .")) { else if (Token::Match(tok->tokAt(-2), "%name% .")) {
const Token *rhsVarTok = tok->tokAt(2); const Token *rhsVarTok = tok->tokAt(2);
if (rhsVarTok && rhsVarTok->varId()) { if (rhsVarTok && rhsVarTok->varId()) {
const unsigned int varid2 = rhsVarTok->varId(); const nonneg int varid2 = rhsVarTok->varId();
const Variables::VariableUsage *var2 = variables.find(varid2); const Variables::VariableUsage *var2 = variables.find(varid2);
// struct member aliased to local variable // struct member aliased to local variable
@ -614,7 +614,7 @@ static const Token* doAssignment(Variables &variables, const Token *tok, bool de
// Possible pointer alias // Possible pointer alias
else if (Token::Match(tok, "%name% = %name% ;")) { else if (Token::Match(tok, "%name% = %name% ;")) {
const unsigned int varid2 = tok->tokAt(2)->varId(); const nonneg int varid2 = tok->tokAt(2)->varId();
const Variables::VariableUsage *var2 = variables.find(varid2); const Variables::VariableUsage *var2 = variables.find(varid2);
if (var2 && (var2->mType == Variables::array || if (var2 && (var2->mType == Variables::array ||
var2->mType == Variables::pointer)) { var2->mType == Variables::pointer)) {
@ -806,7 +806,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const
// Mark template parameters used in declaration as use.. // Mark template parameters used in declaration as use..
if (tok2->strAt(-1) == ">") { if (tok2->strAt(-1) == ">") {
for (const Token *tok3 = tok; tok3 != tok2; tok3 = tok3->next()) { for (const Token *tok3 = tok; tok3 != tok2; tok3 = tok3->next()) {
if (tok3->varId() > 0U) if (tok3->varId())
variables.use(tok3->varId(), tok3); variables.use(tok3->varId(), tok3);
} }
} }
@ -835,7 +835,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const
// Freeing memory (not considered "using" the pointer if it was also allocated in this function) // Freeing memory (not considered "using" the pointer if it was also allocated in this function)
if (Token::Match(tok, "free|g_free|kfree|vfree ( %var% )") || if (Token::Match(tok, "free|g_free|kfree|vfree ( %var% )") ||
(mTokenizer->isCPP() && (Token::Match(tok, "delete %var% ;") || Token::Match(tok, "delete [ ] %var% ;")))) { (mTokenizer->isCPP() && (Token::Match(tok, "delete %var% ;") || Token::Match(tok, "delete [ ] %var% ;")))) {
unsigned int varid = 0; nonneg int varid = 0;
if (tok->str() != "delete") { if (tok->str() != "delete") {
const Token *varTok = tok->tokAt(2); const Token *varTok = tok->tokAt(2);
varid = varTok->varId(); varid = varTok->varId();
@ -893,7 +893,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const
if (tok->next()->tokType() == Token::eIncDecOp) if (tok->next()->tokType() == Token::eIncDecOp)
post = true; post = true;
const unsigned int varid1 = tok->varId(); const nonneg int varid1 = tok->varId();
const Token * const start = tok; const Token * const start = tok;
// assignment in while head.. // assignment in while head..
@ -993,7 +993,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const
// checked for chained assignments // checked for chained assignments
if (tok != start && equal && equal->str() == "=") { if (tok != start && equal && equal->str() == "=") {
const unsigned int varId = tok->varId(); const nonneg int varId = tok->varId();
const Variables::VariableUsage * const var = variables.find(varId); const Variables::VariableUsage * const var = variables.find(varId);
if (var && var->mType != Variables::reference) { if (var && var->mType != Variables::reference) {
@ -1019,7 +1019,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const
tok = tok->link()->next(); tok = tok->link()->next();
} }
const unsigned int varid = tok->varId(); const nonneg int varid = tok->varId();
const Variables::VariableUsage *var = variables.find(varid); const Variables::VariableUsage *var = variables.find(varid);
if (var) { if (var) {
@ -1292,7 +1292,7 @@ void CheckUnusedVar::checkFunctionVariableUsage()
// Check usage of all variables in the current scope.. // Check usage of all variables in the current scope..
for (std::map<unsigned int, Variables::VariableUsage>::const_iterator it = variables.varUsage().begin(); for (std::map<nonneg int, Variables::VariableUsage>::const_iterator it = variables.varUsage().begin();
it != variables.varUsage().end(); it != variables.varUsage().end();
++it) { ++it) {
const Variables::VariableUsage &usage = it->second; const Variables::VariableUsage &usage = it->second;

View File

@ -10,11 +10,11 @@
#include <limits> #include <limits>
#include <memory> #include <memory>
void ProgramMemory::setValue(MathLib::bigint exprid, const ValueFlow::Value& value) void ProgramMemory::setValue(nonneg int exprid, const ValueFlow::Value& value)
{ {
values[exprid] = value; values[exprid] = value;
} }
const ValueFlow::Value* ProgramMemory::getValue(MathLib::bigint exprid) const const ValueFlow::Value* ProgramMemory::getValue(nonneg int exprid) const
{ {
const ProgramMemory::Map::const_iterator it = values.find(exprid); const ProgramMemory::Map::const_iterator it = values.find(exprid);
const bool found = it != values.end() && !it->second.isImpossible(); const bool found = it != values.end() && !it->second.isImpossible();
@ -24,7 +24,7 @@ const ValueFlow::Value* ProgramMemory::getValue(MathLib::bigint exprid) const
return nullptr; return nullptr;
} }
bool ProgramMemory::getIntValue(MathLib::bigint exprid, MathLib::bigint* result) const bool ProgramMemory::getIntValue(nonneg int exprid, MathLib::bigint* result) const
{ {
const ValueFlow::Value* value = getValue(exprid); const ValueFlow::Value* value = getValue(exprid);
if (value && value->isIntValue()) { if (value && value->isIntValue()) {
@ -34,12 +34,12 @@ bool ProgramMemory::getIntValue(MathLib::bigint exprid, MathLib::bigint* result)
return false; return false;
} }
void ProgramMemory::setIntValue(MathLib::bigint exprid, MathLib::bigint value) void ProgramMemory::setIntValue(nonneg int exprid, MathLib::bigint value)
{ {
values[exprid] = ValueFlow::Value(value); values[exprid] = ValueFlow::Value(value);
} }
bool ProgramMemory::getTokValue(MathLib::bigint exprid, const Token** result) const bool ProgramMemory::getTokValue(nonneg int exprid, const Token** result) const
{ {
const ValueFlow::Value* value = getValue(exprid); const ValueFlow::Value* value = getValue(exprid);
if (value && value->isTokValue()) { if (value && value->isTokValue()) {
@ -49,7 +49,7 @@ bool ProgramMemory::getTokValue(MathLib::bigint exprid, const Token** result) co
return false; return false;
} }
bool ProgramMemory::getContainerSizeValue(MathLib::bigint exprid, MathLib::bigint* result) const bool ProgramMemory::getContainerSizeValue(nonneg int exprid, MathLib::bigint* result) const
{ {
const ValueFlow::Value* value = getValue(exprid); const ValueFlow::Value* value = getValue(exprid);
if (value && value->isContainerSizeValue()) { if (value && value->isContainerSizeValue()) {
@ -59,12 +59,12 @@ bool ProgramMemory::getContainerSizeValue(MathLib::bigint exprid, MathLib::bigin
return false; return false;
} }
void ProgramMemory::setUnknown(MathLib::bigint exprid) void ProgramMemory::setUnknown(nonneg int exprid)
{ {
values[exprid].valueType = ValueFlow::Value::ValueType::UNINIT; values[exprid].valueType = ValueFlow::Value::ValueType::UNINIT;
} }
bool ProgramMemory::hasValue(MathLib::bigint exprid) bool ProgramMemory::hasValue(nonneg int exprid)
{ {
return values.find(exprid) != values.end(); return values.find(exprid) != values.end();
} }
@ -291,7 +291,7 @@ void ProgramMemoryState::addState(const Token* tok, const ProgramMemory::Map& va
ProgramMemory pm = state; ProgramMemory pm = state;
fillProgramMemoryFromConditions(pm, tok, nullptr); fillProgramMemoryFromConditions(pm, tok, nullptr);
for (const auto& p:vars) { for (const auto& p:vars) {
MathLib::bigint exprid = p.first; nonneg int exprid = p.first;
const ValueFlow::Value &value = p.second; const ValueFlow::Value &value = p.second;
pm.setValue(exprid, value); pm.setValue(exprid, value);
if (value.varId) if (value.varId)
@ -340,7 +340,7 @@ ProgramMemory getProgramMemory(const Token *tok, const ProgramMemory::Map& vars)
fillProgramMemoryFromConditions(programMemory, tok, nullptr); fillProgramMemoryFromConditions(programMemory, tok, nullptr);
ProgramMemory state; ProgramMemory state;
for (const auto& p:vars) { for (const auto& p:vars) {
MathLib::bigint exprid = p.first; nonneg int exprid = p.first;
const ValueFlow::Value &value = p.second; const ValueFlow::Value &value = p.second;
programMemory.setValue(exprid, value); programMemory.setValue(exprid, value);
if (value.varId) if (value.varId)
@ -351,7 +351,7 @@ ProgramMemory getProgramMemory(const Token *tok, const ProgramMemory::Map& vars)
return programMemory; return programMemory;
} }
ProgramMemory getProgramMemory(const Token* tok, MathLib::bigint exprid, const ValueFlow::Value& value) ProgramMemory getProgramMemory(const Token* tok, nonneg int exprid, const ValueFlow::Value& value)
{ {
ProgramMemory programMemory; ProgramMemory programMemory;
programMemory.replace(getInitialProgramState(tok, value.tokvalue)); programMemory.replace(getInitialProgramState(tok, value.tokvalue));
@ -447,7 +447,7 @@ void execute(const Token *expr,
} }
else if (Token::Match(expr, "++|--")) { else if (Token::Match(expr, "++|--")) {
if (!expr->astOperand1() || expr->astOperand1()->exprId() == 0U) if (!expr->astOperand1() || expr->astOperand1()->exprId() == 0)
*error = true; *error = true;
else { else {
long long intValue; long long intValue;

View File

@ -11,21 +11,21 @@
class Token; class Token;
struct ProgramMemory { struct ProgramMemory {
using Map = std::unordered_map<MathLib::bigint, ValueFlow::Value>; using Map = std::unordered_map<nonneg int, ValueFlow::Value>;
Map values; Map values;
void setValue(MathLib::bigint exprid, const ValueFlow::Value& value); void setValue(nonneg int exprid, const ValueFlow::Value& value);
const ValueFlow::Value* getValue(MathLib::bigint exprid) const; const ValueFlow::Value* getValue(nonneg int exprid) const;
bool getIntValue(MathLib::bigint exprid, MathLib::bigint* result) const; bool getIntValue(nonneg int exprid, MathLib::bigint* result) const;
void setIntValue(MathLib::bigint exprid, MathLib::bigint value); void setIntValue(nonneg int exprid, MathLib::bigint value);
bool getContainerSizeValue(MathLib::bigint exprid, MathLib::bigint* result) const; bool getContainerSizeValue(nonneg int exprid, MathLib::bigint* result) const;
void setUnknown(MathLib::bigint exprid); void setUnknown(nonneg int exprid);
bool getTokValue(MathLib::bigint exprid, const Token** result) const; bool getTokValue(nonneg int exprid, const Token** result) const;
bool hasValue(MathLib::bigint exprid); bool hasValue(nonneg int exprid);
void swap(ProgramMemory &pm); void swap(ProgramMemory &pm);
@ -42,7 +42,7 @@ void programMemoryParseCondition(ProgramMemory& pm, const Token* tok, const Toke
struct ProgramMemoryState { struct ProgramMemoryState {
ProgramMemory state; ProgramMemory state;
std::map<MathLib::bigint, const Token*> origins; std::map<nonneg int, const Token*> origins;
void insert(const ProgramMemory &pm, const Token* origin = nullptr); void insert(const ProgramMemory &pm, const Token* origin = nullptr);
void replace(const ProgramMemory &pm, const Token* origin = nullptr); void replace(const ProgramMemory &pm, const Token* origin = nullptr);
@ -79,7 +79,7 @@ bool conditionIsTrue(const Token *condition, const ProgramMemory &programMemory)
/** /**
* Get program memory by looking backwards from given token. * Get program memory by looking backwards from given token.
*/ */
ProgramMemory getProgramMemory(const Token* tok, MathLib::bigint exprid, const ValueFlow::Value& value); ProgramMemory getProgramMemory(const Token* tok, nonneg int exprid, const ValueFlow::Value& value);
ProgramMemory getProgramMemory(const Token *tok, const ProgramMemory::Map& vars); ProgramMemory getProgramMemory(const Token *tok, const ProgramMemory::Map& vars);

View File

@ -1421,14 +1421,14 @@ void SymbolDatabase::createSymbolDatabaseEscapeFunctions()
void SymbolDatabase::createSymbolDatabaseExprIds() void SymbolDatabase::createSymbolDatabaseExprIds()
{ {
MathLib::bigint base = 0; nonneg int base = 0;
// Find highest varId // Find highest varId
for (const Variable *var : mVariableList) { for (const Variable *var : mVariableList) {
if (!var) if (!var)
continue; continue;
base = std::max<MathLib::bigint>(base, var->declarationId()); base = std::max<MathLib::bigint>(base, var->declarationId());
} }
MathLib::bigint id = base+1; nonneg int id = base + 1;
for (const Scope * scope : functionScopes) { for (const Scope * scope : functionScopes) {
std::unordered_map<std::string, std::vector<Token*>> exprs; std::unordered_map<std::string, std::vector<Token*>> exprs;
@ -1439,6 +1439,10 @@ void SymbolDatabase::createSymbolDatabaseExprIds()
} else if (Token::Match(tok, "(|.|[|%cop%")) { } else if (Token::Match(tok, "(|.|[|%cop%")) {
exprs[tok->str()].push_back(tok); exprs[tok->str()].push_back(tok);
tok->exprId(id++); tok->exprId(id++);
if (id == std::numeric_limits<nonneg int>::max()) {
throw InternalError(nullptr, "Ran out of expression ids.", InternalError::INTERNAL);
}
} }
} }
@ -1453,7 +1457,7 @@ void SymbolDatabase::createSymbolDatabaseExprIds()
continue; continue;
if (!isSameExpression(isCPP(), true, tok1, tok2, mSettings->library, true, false)) if (!isSameExpression(isCPP(), true, tok1, tok2, mSettings->library, true, false))
continue; continue;
MathLib::bigint cid = std::min(tok1->exprId(), tok2->exprId()); nonneg int cid = std::min(tok1->exprId(), tok2->exprId());
tok1->exprId(cid); tok1->exprId(cid);
tok2->exprId(cid); tok2->exprId(cid);
} }

View File

@ -1529,7 +1529,7 @@ static void astStringXml(const Token *tok, nonneg int indent, std::ostream &out)
const std::string strindent(indent, ' '); const std::string strindent(indent, ' ');
out << strindent << "<token str=\"" << tok->str() << '\"'; out << strindent << "<token str=\"" << tok->str() << '\"';
if (tok->varId() > 0U) if (tok->varId())
out << " varId=\"" << MathLib::toString(tok->varId()) << '\"'; out << " varId=\"" << MathLib::toString(tok->varId()) << '\"';
if (tok->variable()) if (tok->variable())
out << " variable=\"" << tok->variable() << '\"'; out << " variable=\"" << tok->variable() << '\"';

View File

@ -65,7 +65,7 @@ struct TokenImpl {
nonneg int mFileIndex; nonneg int mFileIndex;
nonneg int mLineNumber; nonneg int mLineNumber;
nonneg int mColumn; nonneg int mColumn;
MathLib::bigint mExprId; nonneg int mExprId;
// AST.. // AST..
Token *mAstOperand1; Token *mAstOperand1;
@ -811,10 +811,10 @@ public:
} }
} }
MathLib::bigint exprId() const { nonneg int exprId() const {
return mImpl->mExprId; return mImpl->mExprId;
} }
void exprId(MathLib::bigint id) { void exprId(nonneg int id) {
mImpl->mExprId = id; mImpl->mExprId = id;
} }

View File

@ -310,7 +310,7 @@ static void combineValueProperties(const ValueFlow::Value &value1, const ValueFl
if (value2.isIteratorValue()) if (value2.isIteratorValue())
result->valueType = value2.valueType; result->valueType = value2.valueType;
result->condition = value1.condition ? value1.condition : value2.condition; result->condition = value1.condition ? value1.condition : value2.condition;
result->varId = (value1.varId != 0U) ? value1.varId : value2.varId; result->varId = (value1.varId != 0) ? value1.varId : value2.varId;
result->varvalue = (result->varId == value1.varId) ? value1.varvalue : value2.varvalue; result->varvalue = (result->varId == value1.varId) ? value1.varvalue : value2.varvalue;
result->errorPath = (value1.errorPath.empty() ? value2 : value1).errorPath; result->errorPath = (value1.errorPath.empty() ? value2 : value1).errorPath;
result->safe = value1.safe || value2.safe; result->safe = value1.safe || value2.safe;
@ -551,12 +551,12 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
} }
} else { } else {
// is condition only depending on 1 variable? // is condition only depending on 1 variable?
int varId = 0; nonneg int varId = 0;
bool ret = false; bool ret = false;
visitAstNodes(parent->astOperand1(), visitAstNodes(parent->astOperand1(),
[&](const Token *t) { [&](const Token *t) {
if (t->varId()) { if (t->varId()) {
if (varId > 0 || value.varId != 0U) if (varId > 0 || value.varId != 0)
ret = true; ret = true;
varId = t->varId(); varId = t->varId();
} else if (t->str() == "(" && Token::Match(t->previous(), "%name%")) } else if (t->str() == "(" && Token::Match(t->previous(), "%name%"))
@ -626,7 +626,7 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
continue; continue;
if (value1.isIteratorValue() && value2.isIteratorValue()) if (value1.isIteratorValue() && value2.isIteratorValue())
continue; continue;
if (value1.isKnown() || value2.isKnown() || value1.varId == 0U || value2.varId == 0U || if (value1.isKnown() || value2.isKnown() || value1.varId == 0 || value2.varId == 0 ||
(value1.varId == value2.varId && value1.varvalue == value2.varvalue && value1.isIntValue() && (value1.varId == value2.varId && value1.varvalue == value2.varvalue && value1.isIntValue() &&
value2.isIntValue())) { value2.isIntValue())) {
ValueFlow::Value result(0); ValueFlow::Value result(0);
@ -773,12 +773,12 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
for (const ValueFlow::Value &value2 : parent->astOperand2()->values()) { for (const ValueFlow::Value &value2 : parent->astOperand2()->values()) {
if (!value2.isIntValue()) if (!value2.isIntValue())
continue; continue;
if (value1.varId == 0U || value2.varId == 0U || if (value1.varId == 0 || value2.varId == 0 ||
(value1.varId == value2.varId && value1.varvalue == value2.varvalue)) { (value1.varId == value2.varId && value1.varvalue == value2.varvalue)) {
ValueFlow::Value result(0); ValueFlow::Value result(0);
result.condition = value1.condition ? value1.condition : value2.condition; result.condition = value1.condition ? value1.condition : value2.condition;
result.setInconclusive(value1.isInconclusive() | value2.isInconclusive()); result.setInconclusive(value1.isInconclusive() | value2.isInconclusive());
result.varId = (value1.varId != 0U) ? value1.varId : value2.varId; result.varId = (value1.varId != 0) ? value1.varId : value2.varId;
result.varvalue = (result.varId == value1.varId) ? value1.intvalue : value2.intvalue; result.varvalue = (result.varId == value1.varId) ? value1.intvalue : value2.intvalue;
if (value1.valueKind == value2.valueKind) if (value1.valueKind == value2.valueKind)
result.valueKind = value1.valueKind; result.valueKind = value1.valueKind;
@ -961,7 +961,7 @@ static Token * valueFlowSetConstantValue(Token *tok, const Settings *settings, b
// Get number of elements in array // Get number of elements in array
const Token *sz1 = tok->tokAt(2); const Token *sz1 = tok->tokAt(2);
const Token *sz2 = tok->tokAt(7); const Token *sz2 = tok->tokAt(7);
const int varid1 = sz1->varId(); const nonneg int varid1 = sz1->varId();
if (varid1 && if (varid1 &&
sz1->variable() && sz1->variable() &&
sz1->variable()->isArray() && sz1->variable()->isArray() &&
@ -1088,12 +1088,12 @@ static void valueFlowString(TokenList *tokenlist)
static void valueFlowArray(TokenList *tokenlist) static void valueFlowArray(TokenList *tokenlist)
{ {
std::map<int, const Token *> constantArrays; std::map<nonneg int, const Token *> constantArrays;
for (Token *tok = tokenlist->front(); tok; tok = tok->next()) { for (Token *tok = tokenlist->front(); tok; tok = tok->next()) {
if (tok->varId() > 0U) { if (tok->varId() > 0) {
// array // array
const std::map<int, const Token *>::const_iterator it = constantArrays.find(tok->varId()); const std::map<nonneg int, const Token *>::const_iterator it = constantArrays.find(tok->varId());
if (it != constantArrays.end()) { if (it != constantArrays.end()) {
ValueFlow::Value value; ValueFlow::Value value;
value.valueType = ValueFlow::Value::ValueType::TOK; value.valueType = ValueFlow::Value::ValueType::TOK;
@ -1771,7 +1771,7 @@ struct ValueFlowAnalyzer : Analyzer {
virtual bool isAlias(const Token* tok, bool& inconclusive) const = 0; virtual bool isAlias(const Token* tok, bool& inconclusive) const = 0;
using ProgramState = std::unordered_map<MathLib::bigint, ValueFlow::Value>; using ProgramState = std::unordered_map<nonneg int, ValueFlow::Value>;
virtual ProgramState getProgramState() const = 0; virtual ProgramState getProgramState() const = 0;
@ -3662,7 +3662,7 @@ static void valueFlowAfterMove(TokenList *tokenlist, SymbolDatabase* symboldatab
const Variable *var = varTok->variable(); const Variable *var = varTok->variable();
if (!var || (!var->isLocal() && !var->isArgument())) if (!var || (!var->isLocal() && !var->isArgument()))
continue; continue;
const int varId = varTok->varId(); const nonneg int varId = varTok->varId();
const Token * const endOfVarScope = var->scope()->bodyEnd; const Token * const endOfVarScope = var->scope()->bodyEnd;
setTokenValue(varTok, value, settings); setTokenValue(varTok, value, settings);
valueFlowForwardVariable( valueFlowForwardVariable(
@ -3672,7 +3672,7 @@ static void valueFlowAfterMove(TokenList *tokenlist, SymbolDatabase* symboldatab
ValueFlow::Value::MoveKind moveKind; ValueFlow::Value::MoveKind moveKind;
if (!isStdMoveOrStdForwarded(tok, &moveKind, &varTok)) if (!isStdMoveOrStdForwarded(tok, &moveKind, &varTok))
continue; continue;
const int varId = varTok->varId(); const nonneg int varId = varTok->varId();
// x is not MOVED after assignment if code is: x = ... std::move(x) .. ; // x is not MOVED after assignment if code is: x = ... std::move(x) .. ;
const Token *parent = tok->astParent(); const Token *parent = tok->astParent();
while (parent && parent->str() != "=" && parent->str() != "return" && while (parent && parent->str() != "=" && parent->str() != "return" &&
@ -3924,7 +3924,7 @@ static bool isVariableInit(const Token *tok)
static void valueFlowAfterAssign(TokenList *tokenlist, SymbolDatabase* symboldatabase, ErrorLogger *errorLogger, const Settings *settings) static void valueFlowAfterAssign(TokenList *tokenlist, SymbolDatabase* symboldatabase, ErrorLogger *errorLogger, const Settings *settings)
{ {
for (const Scope * scope : symboldatabase->functionScopes) { for (const Scope * scope : symboldatabase->functionScopes) {
std::set<int> aliased; std::set<nonneg int> aliased;
for (Token* tok = const_cast<Token*>(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) { for (Token* tok = const_cast<Token*>(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) {
// Alias // Alias
if (tok->isUnaryOp("&")) { if (tok->isUnaryOp("&")) {
@ -3939,7 +3939,7 @@ static void valueFlowAfterAssign(TokenList *tokenlist, SymbolDatabase* symboldat
// Lhs should be a variable // Lhs should be a variable
if (!tok->astOperand1() || !tok->astOperand1()->exprId()) if (!tok->astOperand1() || !tok->astOperand1()->exprId())
continue; continue;
const int exprid = tok->astOperand1()->exprId(); const nonneg int exprid = tok->astOperand1()->exprId();
if (aliased.find(exprid) != aliased.end()) if (aliased.find(exprid) != aliased.end())
continue; continue;
std::vector<const Variable*> vars = getLHSVariables(tok); std::vector<const Variable*> vars = getLHSVariables(tok);
@ -4025,7 +4025,7 @@ static std::vector<const Variable*> getExprVariables(const Token* expr,
{ {
std::vector<const Variable*> result; std::vector<const Variable*> result;
FwdAnalysis fwdAnalysis(tokenlist->isCPP(), settings->library); FwdAnalysis fwdAnalysis(tokenlist->isCPP(), settings->library);
std::set<int> varids = fwdAnalysis.getExprVarIds(expr); std::set<nonneg int> varids = fwdAnalysis.getExprVarIds(expr);
std::transform(varids.begin(), varids.end(), std::back_inserter(result), [&](int id) { std::transform(varids.begin(), varids.end(), std::back_inserter(result), [&](int id) {
return symboldatabase->getVariableFromVarId(id); return symboldatabase->getVariableFromVarId(id);
}); });
@ -4066,7 +4066,7 @@ struct ConditionHandler {
const std::function< const std::function<
void(const Condition& cond, Token* tok, const Scope* scope, const std::vector<const Variable*>& vars)>& f) const { void(const Condition& cond, Token* tok, const Scope* scope, const std::vector<const Variable*>& vars)>& f) const {
for (const Scope *scope : symboldatabase->functionScopes) { for (const Scope *scope : symboldatabase->functionScopes) {
std::set<unsigned> aliased; std::set<nonneg int> aliased;
for (Token *tok = const_cast<Token *>(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) { for (Token *tok = const_cast<Token *>(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) {
if (Token::Match(tok, "if|while|for (")) if (Token::Match(tok, "if|while|for ("))
continue; continue;
@ -5018,7 +5018,7 @@ struct MultiValueFlowAnalyzer : ValueFlowAnalyzer {
programMemoryParseCondition(pm, condTok, nullptr, getSettings(), scope->type != Scope::eElse); programMemoryParseCondition(pm, condTok, nullptr, getSettings(), scope->type != Scope::eElse);
// ProgramMemory pm = pms.get(endBlock->link()->next(), getProgramState()); // ProgramMemory pm = pms.get(endBlock->link()->next(), getProgramState());
for (const auto& p:pm.values) { for (const auto& p:pm.values) {
int varid = p.first; nonneg int varid = p.first;
if (!symboldatabase->isVarId(varid)) if (!symboldatabase->isVarId(varid))
continue; continue;
ValueFlow::Value value = p.second; ValueFlow::Value value = p.second;
@ -5098,7 +5098,7 @@ static void valueFlowInjectParameter(TokenList* tokenlist, ErrorLogger* errorLog
return; return;
// Set value in function scope.. // Set value in function scope..
const int varid2 = arg->declarationId(); const nonneg int varid2 = arg->declarationId();
if (!varid2) if (!varid2)
return; return;
@ -6531,7 +6531,7 @@ ValueFlow::Value::Value(const Token* c, long long val)
moveKind(MoveKind::NonMovedVariable), moveKind(MoveKind::NonMovedVariable),
varvalue(val), varvalue(val),
condition(c), condition(c),
varId(0U), varId(0),
safe(false), safe(false),
conditional(false), conditional(false),
defaultArg(false), defaultArg(false),