Bug hunting; Avoid uninit false positives with simple analysis
This commit is contained in:
parent
9af288e1dd
commit
592637af61
|
@ -157,6 +157,39 @@ static void integerOverflow(const Token *tok, const ExprEngine::Value &value, Ex
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** check if variable is unconditionally assigned */
|
||||||
|
static bool isVariableAssigned(const Variable *var, const Token *tok, const Token *scopeStart=nullptr)
|
||||||
|
{
|
||||||
|
const Token * const start = scopeStart && precedes(var->nameToken(), scopeStart) ? scopeStart : var->nameToken();
|
||||||
|
|
||||||
|
for (const Token *prev = tok->previous(); prev; prev = prev->previous()) {
|
||||||
|
if (!precedes(start, prev))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (prev->str() == "}") {
|
||||||
|
if (Token::simpleMatch(prev->link()->tokAt(-2), "} else {")) {
|
||||||
|
const Token *elseEnd = prev;
|
||||||
|
const Token *elseStart = prev->link();
|
||||||
|
const Token *ifEnd = elseStart->tokAt(-2);
|
||||||
|
const Token *ifStart = ifEnd->link();
|
||||||
|
if (isVariableAssigned(var, ifEnd, ifStart) && isVariableAssigned(var, elseEnd, elseStart)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prev = prev->link();
|
||||||
|
}
|
||||||
|
if (scopeStart && Token::Match(prev, "return|throw|continue|break"))
|
||||||
|
return true;
|
||||||
|
if (Token::Match(prev, "%varid% =", var->declarationId()))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// bailout; if variable is used previously that is checked first
|
||||||
|
if (!scopeStart && prev->varId() == var->declarationId())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static void uninit(const Token *tok, const ExprEngine::Value &value, ExprEngine::DataBase *dataBase)
|
static void uninit(const Token *tok, const ExprEngine::Value &value, ExprEngine::DataBase *dataBase)
|
||||||
{
|
{
|
||||||
if (!tok->astParent())
|
if (!tok->astParent())
|
||||||
|
@ -256,16 +289,11 @@ static void uninit(const Token *tok, const ExprEngine::Value &value, ExprEngine:
|
||||||
// Are there unconditional assignment?
|
// Are there unconditional assignment?
|
||||||
if (var && Token::Match(var->nameToken(), "%varid% ;| %varid%| =", tok->varId()))
|
if (var && Token::Match(var->nameToken(), "%varid% ;| %varid%| =", tok->varId()))
|
||||||
return;
|
return;
|
||||||
for (const Token *prev = tok->previous(); prev; prev = prev->previous()) {
|
|
||||||
if (!precedes(var->nameToken(), prev))
|
|
||||||
break;
|
|
||||||
if (prev->str() == "}")
|
|
||||||
prev = prev->link();
|
|
||||||
if (Token::Match(prev, "%varid% =", tok->varId()))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tok->variable() && isVariableAssigned(tok->variable(), tok))
|
||||||
|
return;
|
||||||
|
|
||||||
// Uninitialized function argument
|
// Uninitialized function argument
|
||||||
bool inconclusive = false;
|
bool inconclusive = false;
|
||||||
if (Token::Match(tok->astParent(), "[,(]")) {
|
if (Token::Match(tok->astParent(), "[,(]")) {
|
||||||
|
|
Loading…
Reference in New Issue