diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index de68b9808..78f683439 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -1463,6 +1463,19 @@ static bool valueFlowForward(Token * const startToken, } } + else if (Token::Match(tok2, "assert|ASSERT (") && Token::simpleMatch(tok2->linkAt(1), ") ;")) { + const Token * const arg = tok2->next()->astOperand2(); + if (arg != nullptr && arg->str() != ",") { + // Should scope be skipped because variable value is checked? + for (std::list::const_iterator it = values.begin(); it != values.end();) { + if (conditionIsFalse(arg, getProgramMemory(tok2, varid, *it))) + values.erase(it++); + else + ++it; + } + } + } + else if (tok2->str() == "}" && indentlevel == varusagelevel) { ++number_of_if; diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 4db727485..91ce2f96d 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -1796,6 +1796,20 @@ private: "}"; ASSERT_EQUALS(false, testValueOfX(code, 6U, 5)); + // assert after for loop.. + code = "static void f() {\n" + " int x;\n" + " int ctls[10];\n" + " for (x = 0; x <= 10; x++) {\n" + " if (cond)\n" + " break;\n" + " }\n" + " assert(x <= 10);\n" + " ctls[x] = 123;\n" // <- x can't be 11 + "}\n"; + ASSERT_EQUALS(false, testValueOfX(code, 9U, 11)); + + // hang code = "void f() {\n" " for(int i = 0; i < 20; i++)\n"