This commit is contained in:
Paul 2020-09-10 17:06:49 -05:00
parent bb9dbaa8f5
commit 4d1b3e06c7
2 changed files with 39 additions and 5 deletions

View File

@ -10,9 +10,19 @@
struct ForwardTraversal {
enum class Progress { Continue, Break, Skip };
ForwardTraversal(const ValuePtr<ForwardAnalyzer>& analyzer, const Settings* settings)
: analyzer(analyzer), settings(settings), actions(ForwardAnalyzer::Action::None), analyzeOnly(false)
{}
ValuePtr<ForwardAnalyzer> analyzer;
const Settings* settings;
ForwardAnalyzer::Action actions;
bool analyzeOnly;
bool stopUpdates()
{
analyzeOnly = true;
return actions.isModified();
}
std::pair<bool, bool> evalCond(const Token* tok) {
std::vector<int> result = analyzer->evaluate(tok);
@ -92,7 +102,7 @@ struct ForwardTraversal {
std::tie(checkThen, checkElse) = evalCond(condTok);
if (!checkThen && !checkElse) {
// Stop if the value is conditional
if (!traverseUnknown && analyzer->isConditional())
if (!traverseUnknown && analyzer->isConditional() && stopUpdates())
return Progress::Break;
checkThen = true;
checkElse = true;
@ -117,7 +127,7 @@ struct ForwardTraversal {
Progress update(Token* tok) {
ForwardAnalyzer::Action action = analyzer->analyze(tok);
actions |= action;
if (!action.isNone())
if (!action.isNone() && !analyzeOnly)
analyzer->update(tok, action);
if (action.isInconclusive() && !analyzer->lowerToInconclusive())
return Progress::Break;
@ -402,6 +412,7 @@ struct ForwardTraversal {
} else {
tok = endBlock;
}
actions |= (thenAction | elseAction);
if (bail)
return Progress::Break;
if (returnThen && returnElse)
@ -415,7 +426,7 @@ struct ForwardTraversal {
if (checkThen) {
return Progress::Break;
} else {
if (analyzer->isConditional())
if (analyzer->isConditional() && stopUpdates())
return Progress::Break;
analyzer->assume(condTok, false);
}
@ -424,8 +435,8 @@ struct ForwardTraversal {
if (!analyzer->lowerToInconclusive())
return Progress::Break;
} else if (thenAction.isModified() || elseAction.isModified()) {
if (!hasElse && analyzer->isConditional())
return Progress::Break;
if (!hasElse && analyzer->isConditional() && stopUpdates())
return Progress::Break;
if (!analyzer->lowerToPossible())
return Progress::Break;
analyzer->assume(condTok, elseAction.isModified());

View File

@ -2424,6 +2424,29 @@ private:
" }"
"}";
ASSERT_EQUALS(false, testValueOfXKnown(code, 3U, 2));
code = "int f(int i, int j) {\n"
" if (i == 0) {\n"
" if (j < 0)\n"
" return 0;\n"
" i = j+1;\n"
" }\n"
" int x = i;\n"
" return x;\n"
"}\n";
ASSERT_EQUALS(false, testValueOfX(code, 8U, 0));
code = "int f(int i, int j) {\n"
" if (i == 0) {\n"
" if (j < 0)\n"
" return 0;\n"
" if (j < 0)\n"
" i = j+1;\n"
" }\n"
" int x = i;\n"
" return x;\n"
"}\n";
ASSERT_EQUALS(true, testValueOfX(code, 9U, 0));
}
void valueFlowAfterConditionExpr() {