parent
597d0fa35b
commit
b55c587ab2
|
@ -1229,7 +1229,9 @@ bool isVariablesChanged(const Token* start,
|
||||||
std::transform(vars.begin(), vars.end(), std::inserter(varids, varids.begin()), [](const Variable* var) {
|
std::transform(vars.begin(), vars.end(), std::inserter(varids, varids.begin()), [](const Variable* var) {
|
||||||
return var->declarationId();
|
return var->declarationId();
|
||||||
});
|
});
|
||||||
const bool globalvar = std::any_of(vars.begin(), vars.end(), [](const Variable* var) { return var->isGlobal(); });
|
const bool globalvar = std::any_of(vars.begin(), vars.end(), [](const Variable* var) {
|
||||||
|
return var->isGlobal();
|
||||||
|
});
|
||||||
for (const Token* tok = start; tok != end; tok = tok->next()) {
|
for (const Token* tok = start; tok != end; tok = tok->next()) {
|
||||||
if (tok->varId() == 0 || varids.count(tok->varId()) == 0) {
|
if (tok->varId() == 0 || varids.count(tok->varId()) == 0) {
|
||||||
if (globalvar && Token::Match(tok, "%name% ("))
|
if (globalvar && Token::Match(tok, "%name% ("))
|
||||||
|
|
|
@ -2366,7 +2366,7 @@ static bool valueFlowForwardVariable(Token* const startToken,
|
||||||
errorLogger,
|
errorLogger,
|
||||||
tok2,
|
tok2,
|
||||||
"variable " + var->name() +
|
"variable " + var->name() +
|
||||||
" valueFlowForwardVariable, bailing out since it's unknown if conditional return is executed");
|
" valueFlowForwardVariable, bailing out since it's unknown if conditional return is executed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2392,7 +2392,7 @@ static bool valueFlowForwardVariable(Token* const startToken,
|
||||||
errorLogger,
|
errorLogger,
|
||||||
tok2,
|
tok2,
|
||||||
"variable " + var->name() +
|
"variable " + var->name() +
|
||||||
" valueFlowForwardVariable, conditional return is assumed to be executed");
|
" valueFlowForwardVariable, conditional return is assumed to be executed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2543,15 +2543,15 @@ static bool valueFlowForwardVariable(Token* const startToken,
|
||||||
const Token * const startToken1 = tok2->linkAt(1)->next();
|
const Token * const startToken1 = tok2->linkAt(1)->next();
|
||||||
|
|
||||||
bool vfresult = valueFlowForwardVariable(startToken1->next(),
|
bool vfresult = valueFlowForwardVariable(startToken1->next(),
|
||||||
startToken1->link(),
|
startToken1->link(),
|
||||||
var,
|
var,
|
||||||
varid,
|
varid,
|
||||||
truevalues,
|
truevalues,
|
||||||
constValue,
|
constValue,
|
||||||
subFunction,
|
subFunction,
|
||||||
tokenlist,
|
tokenlist,
|
||||||
errorLogger,
|
errorLogger,
|
||||||
settings);
|
settings);
|
||||||
|
|
||||||
if (!condAlwaysFalse && isVariableChanged(startToken1, startToken1->link(), varid, var->isGlobal(), settings, tokenlist->isCPP())) {
|
if (!condAlwaysFalse && isVariableChanged(startToken1, startToken1->link(), varid, var->isGlobal(), settings, tokenlist->isCPP())) {
|
||||||
removeValues(values, truevalues);
|
removeValues(values, truevalues);
|
||||||
|
@ -3124,15 +3124,21 @@ const Token* solveExprValues(const Token* expr, std::list<ValueFlow::Value>& val
|
||||||
if (binaryTok && expr->str().size() == 1) {
|
if (binaryTok && expr->str().size() == 1) {
|
||||||
switch (expr->str()[0]) {
|
switch (expr->str()[0]) {
|
||||||
case '+': {
|
case '+': {
|
||||||
transformIntValues(values, [&](MathLib::bigint x) { return x - intval; });
|
transformIntValues(values, [&](MathLib::bigint x) {
|
||||||
|
return x - intval;
|
||||||
|
});
|
||||||
return solveExprValues(binaryTok, values);
|
return solveExprValues(binaryTok, values);
|
||||||
}
|
}
|
||||||
case '*': {
|
case '*': {
|
||||||
transformIntValues(values, [&](MathLib::bigint x) { return x / intval; });
|
transformIntValues(values, [&](MathLib::bigint x) {
|
||||||
|
return x / intval;
|
||||||
|
});
|
||||||
return solveExprValues(binaryTok, values);
|
return solveExprValues(binaryTok, values);
|
||||||
}
|
}
|
||||||
case '^': {
|
case '^': {
|
||||||
transformIntValues(values, [&](MathLib::bigint x) { return x ^ intval; });
|
transformIntValues(values, [&](MathLib::bigint x) {
|
||||||
|
return x ^ intval;
|
||||||
|
});
|
||||||
return solveExprValues(binaryTok, values);
|
return solveExprValues(binaryTok, values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4377,9 +4383,9 @@ void insertImpossible(std::list<ValueFlow::Value>& values, const std::list<Value
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<const Variable*> getExprVariables(const Token* expr,
|
static std::vector<const Variable*> getExprVariables(const Token* expr,
|
||||||
const TokenList* tokenlist,
|
const TokenList* tokenlist,
|
||||||
const SymbolDatabase* symboldatabase,
|
const SymbolDatabase* symboldatabase,
|
||||||
const Settings* settings)
|
const Settings* settings)
|
||||||
{
|
{
|
||||||
std::vector<const Variable*> result;
|
std::vector<const Variable*> result;
|
||||||
FwdAnalysis fwdAnalysis(tokenlist->isCPP(), settings->library);
|
FwdAnalysis fwdAnalysis(tokenlist->isCPP(), settings->library);
|
||||||
|
@ -4399,7 +4405,7 @@ struct ValueFlowConditionHandler {
|
||||||
Condition() : vartok(nullptr), true_values(), false_values() {}
|
Condition() : vartok(nullptr), true_values(), false_values() {}
|
||||||
};
|
};
|
||||||
std::function<bool(Token* start, const Token* stop, const Token* exprTok, const std::list<ValueFlow::Value>& values, bool constValue)>
|
std::function<bool(Token* start, const Token* stop, const Token* exprTok, const std::list<ValueFlow::Value>& values, bool constValue)>
|
||||||
forward;
|
forward;
|
||||||
std::function<Condition(Token *tok)> parse;
|
std::function<Condition(Token *tok)> parse;
|
||||||
|
|
||||||
void afterCondition(TokenList *tokenlist,
|
void afterCondition(TokenList *tokenlist,
|
||||||
|
@ -4426,12 +4432,12 @@ struct ValueFlowConditionHandler {
|
||||||
|
|
||||||
std::vector<const Variable*> vars = getExprVariables(cond.vartok, tokenlist, symboldatabase, settings);
|
std::vector<const Variable*> vars = getExprVariables(cond.vartok, tokenlist, symboldatabase, settings);
|
||||||
if (std::any_of(vars.begin(), vars.end(), [](const Variable* var) {
|
if (std::any_of(vars.begin(), vars.end(), [](const Variable* var) {
|
||||||
return !var || !(var->isLocal() || var->isGlobal() || var->isArgument());
|
return !var || !(var->isLocal() || var->isGlobal() || var->isArgument());
|
||||||
}))
|
}))
|
||||||
continue;
|
continue;
|
||||||
if (std::any_of(vars.begin(), vars.end(), [&](const Variable* var) {
|
if (std::any_of(vars.begin(), vars.end(), [&](const Variable* var) {
|
||||||
return aliased.find(var->declarationId()) != aliased.end();
|
return aliased.find(var->declarationId()) != aliased.end();
|
||||||
})) {
|
})) {
|
||||||
if (settings->debugwarnings)
|
if (settings->debugwarnings)
|
||||||
bailout(tokenlist,
|
bailout(tokenlist,
|
||||||
errorLogger,
|
errorLogger,
|
||||||
|
@ -4461,12 +4467,12 @@ struct ValueFlowConditionHandler {
|
||||||
tokenlist->isCPP(), false, cond.vartok, rhstok, settings->library, true, false))
|
tokenlist->isCPP(), false, cond.vartok, rhstok, settings->library, true, false))
|
||||||
setTokenValue(rhstok, cond.true_values.front(), settings);
|
setTokenValue(rhstok, cond.true_values.front(), settings);
|
||||||
else if (Token::Match(rhstok, "++|--|=") && isSameExpression(tokenlist->isCPP(),
|
else if (Token::Match(rhstok, "++|--|=") && isSameExpression(tokenlist->isCPP(),
|
||||||
false,
|
false,
|
||||||
cond.vartok,
|
cond.vartok,
|
||||||
rhstok->astOperand1(),
|
rhstok->astOperand1(),
|
||||||
settings->library,
|
settings->library,
|
||||||
true,
|
true,
|
||||||
false)) {
|
false)) {
|
||||||
assign = true;
|
assign = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -4546,7 +4552,7 @@ struct ValueFlowConditionHandler {
|
||||||
errorLogger,
|
errorLogger,
|
||||||
startTokens[changeBlock]->link(),
|
startTokens[changeBlock]->link(),
|
||||||
"valueFlowAfterCondition: " + cond.vartok->expressionString() +
|
"valueFlowAfterCondition: " + cond.vartok->expressionString() +
|
||||||
" is changed in conditional block");
|
" is changed in conditional block");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4621,7 +4627,7 @@ static void valueFlowAfterCondition(TokenList *tokenlist,
|
||||||
const Token* stop,
|
const Token* stop,
|
||||||
const Token* vartok,
|
const Token* vartok,
|
||||||
const std::list<ValueFlow::Value>& values,
|
const std::list<ValueFlow::Value>& values,
|
||||||
bool constValue) {
|
bool constValue) {
|
||||||
valueFlowForward(start->next(), stop, vartok, values, constValue, false, tokenlist, errorLogger, settings);
|
valueFlowForward(start->next(), stop, vartok, values, constValue, false, tokenlist, errorLogger, settings);
|
||||||
std::vector<const Variable*> vars = getExprVariables(vartok, tokenlist, symboldatabase, settings);
|
std::vector<const Variable*> vars = getExprVariables(vartok, tokenlist, symboldatabase, settings);
|
||||||
return isVariablesChanged(start, stop, 0, vars, settings, tokenlist->isCPP());
|
return isVariablesChanged(start, stop, 0, vars, settings, tokenlist->isCPP());
|
||||||
|
@ -6049,16 +6055,16 @@ static void valueFlowContainerAfterCondition(TokenList *tokenlist,
|
||||||
{
|
{
|
||||||
ValueFlowConditionHandler handler;
|
ValueFlowConditionHandler handler;
|
||||||
handler.forward =
|
handler.forward =
|
||||||
[&](Token* start, const Token* stop, const Token* vartok, const std::list<ValueFlow::Value>& values, bool) {
|
[&](Token* start, const Token* stop, const Token* vartok, const std::list<ValueFlow::Value>& values, bool) {
|
||||||
// TODO: Forward multiple values
|
// TODO: Forward multiple values
|
||||||
if (values.empty())
|
if (values.empty())
|
||||||
return false;
|
return false;
|
||||||
const Variable* var = vartok->variable();
|
const Variable* var = vartok->variable();
|
||||||
if (!var)
|
if (!var)
|
||||||
return false;
|
return false;
|
||||||
valueFlowContainerForward(start, var->declarationId(), values.front(), settings, tokenlist->isCPP());
|
valueFlowContainerForward(start, var->declarationId(), values.front(), settings, tokenlist->isCPP());
|
||||||
return isContainerSizeChanged(var->declarationId(), start, stop);
|
return isContainerSizeChanged(var->declarationId(), start, stop);
|
||||||
};
|
};
|
||||||
handler.parse = [&](const Token *tok) {
|
handler.parse = [&](const Token *tok) {
|
||||||
ValueFlowConditionHandler::Condition cond;
|
ValueFlowConditionHandler::Condition cond;
|
||||||
ValueFlow::Value true_value;
|
ValueFlow::Value true_value;
|
||||||
|
|
|
@ -2309,8 +2309,7 @@ private:
|
||||||
ASSERT_EQUALS(true, testValueOfX(code, 6U, 0));
|
ASSERT_EQUALS(true, testValueOfX(code, 6U, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void valueFlowAfterConditionExpr()
|
void valueFlowAfterConditionExpr() {
|
||||||
{
|
|
||||||
const char* code;
|
const char* code;
|
||||||
|
|
||||||
code = "void f(int* p) {\n"
|
code = "void f(int* p) {\n"
|
||||||
|
|
Loading…
Reference in New Issue