diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 8d28613f2..86b4c9b3d 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -1459,7 +1459,8 @@ static bool valueFlowForward(Token * const startToken, } bool bailoutflag = false; - for (std::list::const_iterator it = values.begin(); it != values.end(); ++it) { + const Token * const start1 = iselse ? tok2->link()->linkAt(-2) : nullptr; + for (std::list::const_iterator it = values.begin(); it != values.end();) { if (!iselse && conditionIsTrue(condition, getProgramMemory(condition->astParent(), varid, *it))) { bailoutflag = true; break; @@ -1468,12 +1469,19 @@ static bool valueFlowForward(Token * const startToken, bailoutflag = true; break; } + if (iselse && it->isPossible() && isVariableChanged(start1, start1->link(), varid, var->isGlobal(), settings)) + values.erase(it++); + else + ++it; } if (bailoutflag) { if (settings->debugwarnings) bailout(tokenlist, errorLogger, tok2, "variable " + var->name() + " valueFlowForward, conditional return is assumed to be executed"); return false; } + + if (values.empty()) + return true; } else if (indentlevel <= 0 && Token::simpleMatch(tok2->link()->previous(), "else {") && !isReturnScope(tok2->link()->tokAt(-2)) && diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 4a9cba922..1825c28d9 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -42,10 +42,11 @@ private: Settings settings; void run() { - // strcpy cfg + // strcpy, abort cfg const char cfg[] = "\n" "\n" " \n" + " true \n" // abort is a noreturn function ""; settings.library.loadxmldata(cfg, sizeof(cfg)); @@ -2770,6 +2771,18 @@ private: "}"; values = tokenValues(code, "x >"); ASSERT_EQUALS(true, values.size() == 1U && values.front().isIntValue()); + + // #8348 - noreturn else + code = "int test_input_int(int a, int b) {\n" + " int x;\n" + " if (a == 1)\n" + " x = b;\n" + " else\n" + " abort();\n" + " a = x + 1;\n" + "}\n"; + values = tokenValues(code, "x +"); + ASSERT_EQUALS(true, values.empty()); } };