Forward values after assignment in valueFlowReverse (#2226)
* Forward values after assignment in valueFlowReverse * Rename variables * Format
This commit is contained in:
parent
b79283306f
commit
997803869d
|
@ -1625,7 +1625,8 @@ static bool isUnchanged(const Token *startToken, const Token *endToken, const st
|
|||
struct FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const Token *startToken, const Token *endToken, const std::set<int> &exprVarIds, bool local, bool inInnerClass)
|
||||
{
|
||||
// Parse the given tokens
|
||||
for (const Token *tok = startToken; tok != endToken; tok = tok->next()) {
|
||||
|
||||
for (const Token* tok = startToken; precedes(tok, endToken); tok = tok->next()) {
|
||||
if (Token::simpleMatch(tok, "try {")) {
|
||||
// TODO: handle try
|
||||
return Result(Result::Type::BAILOUT);
|
||||
|
|
|
@ -1841,6 +1841,16 @@ static void valueFlowGlobalStaticVar(TokenList *tokenList, const Settings *setti
|
|||
}
|
||||
}
|
||||
|
||||
static void valueFlowForward(Token* startToken,
|
||||
const Token* endToken,
|
||||
const Token* exprTok,
|
||||
std::list<ValueFlow::Value> values,
|
||||
const bool constValue,
|
||||
const bool subFunction,
|
||||
TokenList* const tokenlist,
|
||||
ErrorLogger* const errorLogger,
|
||||
const Settings* settings);
|
||||
|
||||
static void valueFlowReverse(TokenList *tokenlist,
|
||||
Token *tok,
|
||||
const Token * const varToken,
|
||||
|
@ -1865,8 +1875,30 @@ static void valueFlowReverse(TokenList *tokenlist,
|
|||
}
|
||||
|
||||
if (tok2->varId() == varid) {
|
||||
if (tok2->hasKnownValue())
|
||||
break;
|
||||
// bailout: assignment
|
||||
if (Token::Match(tok2->previous(), "!!* %name% =")) {
|
||||
Token* assignTok = const_cast<Token*>(tok2->next()->astOperand2());
|
||||
if (!assignTok->hasKnownValue()) {
|
||||
std::list<ValueFlow::Value> values = {val};
|
||||
setTokenValue(assignTok, val, settings);
|
||||
if (val2.condition) {
|
||||
setTokenValue(assignTok, val2, settings);
|
||||
values.push_back(val2);
|
||||
}
|
||||
const Token* startForwardToken = nextAfterAstRightmostLeaf(tok2->next());
|
||||
const Token* endForwardToken = tok->scope() ? tok->scope()->bodyEnd : tok;
|
||||
valueFlowForward(const_cast<Token*>(startForwardToken),
|
||||
endForwardToken,
|
||||
assignTok,
|
||||
values,
|
||||
false,
|
||||
false,
|
||||
tokenlist,
|
||||
errorLogger,
|
||||
settings);
|
||||
}
|
||||
if (settings->debugwarnings)
|
||||
bailout(tokenlist, errorLogger, tok2, "assignment of " + tok2->str());
|
||||
break;
|
||||
|
@ -2062,6 +2094,17 @@ static void valueFlowReverse(TokenList *tokenlist,
|
|||
}
|
||||
}
|
||||
|
||||
static bool isConditionKnown(const Token* tok, bool then)
|
||||
{
|
||||
const char* op = "||";
|
||||
if (then)
|
||||
op = "&&";
|
||||
const Token* parent = tok->astParent();
|
||||
while (parent && parent->str() == op)
|
||||
parent = parent->astParent();
|
||||
return (parent && parent->str() == "(");
|
||||
}
|
||||
|
||||
static void valueFlowBeforeCondition(TokenList *tokenlist, SymbolDatabase *symboldatabase, ErrorLogger *errorLogger, const Settings *settings)
|
||||
{
|
||||
for (const Scope * scope : symboldatabase->functionScopes) {
|
||||
|
@ -4311,17 +4354,6 @@ static void valueFlowAfterAssign(TokenList *tokenlist, SymbolDatabase* symboldat
|
|||
}
|
||||
}
|
||||
|
||||
static bool isConditionKnown(const Token* tok, bool then)
|
||||
{
|
||||
const char * op = "||";
|
||||
if (then)
|
||||
op = "&&";
|
||||
const Token* parent = tok->astParent();
|
||||
while (parent && parent->str() == op)
|
||||
parent = parent->astParent();
|
||||
return (parent && parent->str() == "(");
|
||||
}
|
||||
|
||||
static void valueFlowSetConditionToKnown(const Token* tok, std::list<ValueFlow::Value>& values, bool then)
|
||||
{
|
||||
if (values.empty())
|
||||
|
|
|
@ -79,6 +79,7 @@ private:
|
|||
TEST_CASE(valueFlowBeforeConditionSizeof);
|
||||
TEST_CASE(valueFlowBeforeConditionSwitch);
|
||||
TEST_CASE(valueFlowBeforeConditionTernaryOp);
|
||||
TEST_CASE(valueFlowBeforeConditionForward);
|
||||
|
||||
TEST_CASE(valueFlowAfterAssign);
|
||||
TEST_CASE(valueFlowAfterCondition);
|
||||
|
@ -1410,6 +1411,25 @@ private:
|
|||
errout.str());
|
||||
}
|
||||
|
||||
void valueFlowBeforeConditionForward()
|
||||
{
|
||||
const char* code;
|
||||
|
||||
code = "void f(int a) {\n"
|
||||
" int x = a;\n"
|
||||
" if (a == 123) {}\n"
|
||||
" int b = x;\n"
|
||||
"}";
|
||||
ASSERT_EQUALS(true, testValueOfX(code, 4U, 123));
|
||||
|
||||
code = "void f(int a) {\n"
|
||||
" int x = a;\n"
|
||||
" if (a != 123) {}\n"
|
||||
" int b = x;\n"
|
||||
"}";
|
||||
ASSERT_EQUALS(true, testValueOfX(code, 4U, 123));
|
||||
}
|
||||
|
||||
void valueFlowAfterAssign() {
|
||||
const char *code;
|
||||
|
||||
|
|
Loading…
Reference in New Issue