diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 8686207b4..b827db11d 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -690,7 +690,7 @@ static bool valueFlowForward(Token * const startToken, ++indentlevel; else if (indentlevel >= 0 && tok2->str() == "}") { --indentlevel; - if (indentlevel == 0 && isReturn(tok2) && Token::Match(tok2->link()->previous(), "else|) {")) { + if (indentlevel <= 0 && isReturn(tok2) && Token::Match(tok2->link()->previous(), "else|) {")) { const Token *condition = tok2->link(); const bool iselse = Token::simpleMatch(condition->tokAt(-2), "} else {"); if (iselse) @@ -830,6 +830,19 @@ static bool valueFlowForward(Token * const startToken, } } + // stop after conditional noreturn scopes that are executed + if (isReturn(end)) { + std::list::iterator it; + for (it = values.begin(); it != values.end();) { + if (conditionIsTrue(tok2->next()->astOperand2(), getProgramMemory(tok2, varid, *it))) + values.erase(it++); + else + it++; + } + if (values.empty()) + return false; + } + // noreturn scopes.. if ((number_of_if > 0 || Token::findmatch(tok2, "%varid%", start, varid)) && (Token::findmatch(start, "return|continue|break|throw", end) || diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 91dc9f2d9..edb3c8aff 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -816,6 +816,18 @@ private: "}"; ASSERT_EQUALS(true, testValueOfX(code, 5U, 2)); + code = "void f(int mode) {\n" + " struct ABC *x;\n" + "\n" + " if (mode) { x = &y; }\n" + " else { x = NULL; }\n" + "\n" + " if (!x) exit(1);\n" + "\n" + " a = x->a;\n" // <- x can't be 0 + "}"; + ASSERT_EQUALS(false, testValueOfX(code, 9U, 0)); + // multivariables code = "void f(int a) {\n" " int x = a;\n"