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)
|
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
|
// 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 {")) {
|
if (Token::simpleMatch(tok, "try {")) {
|
||||||
// TODO: handle try
|
// TODO: handle try
|
||||||
return Result(Result::Type::BAILOUT);
|
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,
|
static void valueFlowReverse(TokenList *tokenlist,
|
||||||
Token *tok,
|
Token *tok,
|
||||||
const Token * const varToken,
|
const Token * const varToken,
|
||||||
|
@ -1865,8 +1875,30 @@ static void valueFlowReverse(TokenList *tokenlist,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tok2->varId() == varid) {
|
if (tok2->varId() == varid) {
|
||||||
|
if (tok2->hasKnownValue())
|
||||||
|
break;
|
||||||
// bailout: assignment
|
// bailout: assignment
|
||||||
if (Token::Match(tok2->previous(), "!!* %name% =")) {
|
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)
|
if (settings->debugwarnings)
|
||||||
bailout(tokenlist, errorLogger, tok2, "assignment of " + tok2->str());
|
bailout(tokenlist, errorLogger, tok2, "assignment of " + tok2->str());
|
||||||
break;
|
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)
|
static void valueFlowBeforeCondition(TokenList *tokenlist, SymbolDatabase *symboldatabase, ErrorLogger *errorLogger, const Settings *settings)
|
||||||
{
|
{
|
||||||
for (const Scope * scope : symboldatabase->functionScopes) {
|
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)
|
static void valueFlowSetConditionToKnown(const Token* tok, std::list<ValueFlow::Value>& values, bool then)
|
||||||
{
|
{
|
||||||
if (values.empty())
|
if (values.empty())
|
||||||
|
|
|
@ -79,6 +79,7 @@ private:
|
||||||
TEST_CASE(valueFlowBeforeConditionSizeof);
|
TEST_CASE(valueFlowBeforeConditionSizeof);
|
||||||
TEST_CASE(valueFlowBeforeConditionSwitch);
|
TEST_CASE(valueFlowBeforeConditionSwitch);
|
||||||
TEST_CASE(valueFlowBeforeConditionTernaryOp);
|
TEST_CASE(valueFlowBeforeConditionTernaryOp);
|
||||||
|
TEST_CASE(valueFlowBeforeConditionForward);
|
||||||
|
|
||||||
TEST_CASE(valueFlowAfterAssign);
|
TEST_CASE(valueFlowAfterAssign);
|
||||||
TEST_CASE(valueFlowAfterCondition);
|
TEST_CASE(valueFlowAfterCondition);
|
||||||
|
@ -1410,6 +1411,25 @@ private:
|
||||||
errout.str());
|
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() {
|
void valueFlowAfterAssign() {
|
||||||
const char *code;
|
const char *code;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue