Skip to content

Commit e14e86c

Browse files
committed
ValueFlow: only set values in conditional code in subfunctions when sure
1 parent 807b653 commit e14e86c

2 files changed

Lines changed: 25 additions & 8 deletions

File tree

lib/valueflow.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,6 +1242,7 @@ static bool valueFlowForward(Token * const startToken,
12421242
const unsigned int varid,
12431243
std::list<ValueFlow::Value> values,
12441244
const bool constValue,
1245+
const bool subFunction,
12451246
TokenList * const tokenlist,
12461247
ErrorLogger * const errorLogger,
12471248
const Settings * const settings)
@@ -1363,7 +1364,11 @@ static bool valueFlowForward(Token * const startToken,
13631364
// Should scope be skipped because variable value is checked?
13641365
std::list<ValueFlow::Value> truevalues;
13651366
for (std::list<ValueFlow::Value>::const_iterator it = values.begin(); it != values.end(); ++it) {
1366-
if (condAlwaysTrue || !conditionIsFalse(condTok, getProgramMemory(tok2, varid, *it)))
1367+
if (condAlwaysTrue)
1368+
truevalues.push_back(*it);
1369+
else if (subFunction && conditionIsTrue(condTok, getProgramMemory(tok2, varid, *it)))
1370+
truevalues.push_back(*it);
1371+
else if (!subFunction && !conditionIsFalse(condTok, getProgramMemory(tok2, varid, *it)))
13671372
truevalues.push_back(*it);
13681373
}
13691374
if (truevalues.size() != values.size() || condAlwaysTrue) {
@@ -1376,6 +1381,7 @@ static bool valueFlowForward(Token * const startToken,
13761381
varid,
13771382
truevalues,
13781383
constValue,
1384+
subFunction,
13791385
tokenlist,
13801386
errorLogger,
13811387
settings);
@@ -1872,7 +1878,7 @@ static void valueFlowAfterMove(TokenList *tokenlist, SymbolDatabase* symboldatab
18721878
const unsigned int varId = varTok->varId();
18731879
const Token * const endOfVarScope = var->typeStartToken()->scope()->classEnd;
18741880
setTokenValue(varTok, value, settings);
1875-
valueFlowForward(varTok->next(), endOfVarScope, var, varId, values, false, tokenlist, errorLogger, settings);
1881+
valueFlowForward(varTok->next(), endOfVarScope, var, varId, values, false, false, tokenlist, errorLogger, settings);
18761882
continue;
18771883
}
18781884
ValueFlow::Value::MoveKind moveKind;
@@ -1904,7 +1910,7 @@ static void valueFlowAfterMove(TokenList *tokenlist, SymbolDatabase* symboldatab
19041910
const Token * openParentesisOfMove = findOpenParentesisOfMove(varTok);
19051911
const Token * endOfFunctionCall = findEndOfFunctionCallForParameter(openParentesisOfMove);
19061912
if (endOfFunctionCall)
1907-
valueFlowForward(const_cast<Token *>(endOfFunctionCall), endOfVarScope, var, varId, values, false, tokenlist, errorLogger, settings);
1913+
valueFlowForward(const_cast<Token *>(endOfFunctionCall), endOfVarScope, var, varId, values, false, false, tokenlist, errorLogger, settings);
19081914
}
19091915
}
19101916
}
@@ -1965,7 +1971,7 @@ static void valueFlowAfterAssign(TokenList *tokenlist, SymbolDatabase* symboldat
19651971
// Skip RHS
19661972
const Token * nextExpression = nextAfterAstRightmostLeaf(tok);
19671973

1968-
valueFlowForward(const_cast<Token *>(nextExpression), endOfVarScope, var, varid, values, constValue, tokenlist, errorLogger, settings);
1974+
valueFlowForward(const_cast<Token *>(nextExpression), endOfVarScope, var, varid, values, constValue, false, tokenlist, errorLogger, settings);
19691975
}
19701976
}
19711977
}
@@ -2089,7 +2095,7 @@ static void valueFlowAfterCondition(TokenList *tokenlist, SymbolDatabase* symbol
20892095
}
20902096

20912097
if (startToken) {
2092-
if (!valueFlowForward(startToken->next(), startToken->link(), var, varid, values, true, tokenlist, errorLogger, settings))
2098+
if (!valueFlowForward(startToken->next(), startToken->link(), var, varid, values, true, false, tokenlist, errorLogger, settings))
20932099
continue;
20942100
if (isVariableChanged(startToken, startToken->link(), varid, settings)) {
20952101
// TODO: The endToken should not be startToken->link() in the valueFlowForward call
@@ -2125,7 +2131,7 @@ static void valueFlowAfterCondition(TokenList *tokenlist, SymbolDatabase* symbol
21252131
// TODO: constValue could be true if there are no assignments in the conditional blocks and
21262132
// perhaps if there are no && and no || in the condition
21272133
bool constValue = false;
2128-
valueFlowForward(after->next(), top->scope()->classEnd, var, varid, values, constValue, tokenlist, errorLogger, settings);
2134+
valueFlowForward(after->next(), top->scope()->classEnd, var, varid, values, constValue, false, tokenlist, errorLogger, settings);
21292135
}
21302136
}
21312137
}
@@ -2503,6 +2509,7 @@ static void valueFlowForLoopSimplifyAfter(Token *fortok, unsigned int varid, con
25032509
varid,
25042510
values,
25052511
false,
2512+
false,
25062513
tokenlist,
25072514
errorLogger,
25082515
settings);
@@ -2566,7 +2573,7 @@ static void valueFlowInjectParameter(TokenList* tokenlist, ErrorLogger* errorLog
25662573
if (!varid2)
25672574
return;
25682575

2569-
valueFlowForward(const_cast<Token*>(functionScope->classStart->next()), functionScope->classEnd, arg, varid2, argvalues, false, tokenlist, errorLogger, settings);
2576+
valueFlowForward(const_cast<Token*>(functionScope->classStart->next()), functionScope->classEnd, arg, varid2, argvalues, false, true, tokenlist, errorLogger, settings);
25702577
}
25712578

25722579
static void valueFlowSwitchVariable(TokenList *tokenlist, SymbolDatabase* symboldatabase, ErrorLogger *errorLogger, const Settings *settings)
@@ -2614,7 +2621,7 @@ static void valueFlowSwitchVariable(TokenList *tokenlist, SymbolDatabase* symbol
26142621
settings);
26152622
}
26162623
if (vartok->variable()->scope()) // #7257
2617-
valueFlowForward(tok, vartok->variable()->scope()->classEnd, vartok->variable(), vartok->varId(), values, false, tokenlist, errorLogger, settings);
2624+
valueFlowForward(tok, vartok->variable()->scope()->classEnd, vartok->variable(), vartok->varId(), values, false, false, tokenlist, errorLogger, settings);
26182625
}
26192626
}
26202627
}

test/testvalueflow.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1974,6 +1974,16 @@ class TestValueFlow : public TestFixture {
19741974
"};";
19751975
ASSERT_EQUALS(true, testValueOfX(code, 3U, 123));
19761976

1977+
code = "void foo(int x, int y) {\n"
1978+
" if (y == 1) {\n"
1979+
" a = x;\n" // <- x is not 1
1980+
" }\n"
1981+
"}\n"
1982+
"\n"
1983+
"void bar() {\n"
1984+
" foo(1, 10);\n"
1985+
"}";
1986+
ASSERT_EQUALS(false, testValueOfX(code, 3U, 1));
19771987
}
19781988

19791989
void valueFlowFunctionReturn() {

0 commit comments

Comments
 (0)