diff --git a/lib/forwardanalyzer.cpp b/lib/forwardanalyzer.cpp index 2019b5287..c258ee04d 100644 --- a/lib/forwardanalyzer.cpp +++ b/lib/forwardanalyzer.cpp @@ -329,6 +329,7 @@ struct ForwardTraversal { Token* initTok = nullptr, Token* stepTok = nullptr) { const bool isDoWhile = precedes(endBlock, condTok); + const bool alwaysEnterLoop = !condTok || (condTok->hasKnownIntValue() && condTok->values().front().intvalue != 0); Analyzer::Action bodyAnalysis = analyzeScope(endBlock); Analyzer::Action allAnalysis = bodyAnalysis; if (condTok) @@ -357,6 +358,8 @@ struct ForwardTraversal { if (checkElse) return Progress::Continue; } + if (allAnalysis.isModified() && alwaysEnterLoop) + return Break(Terminate::Bail); std::vector ftv = tryForkScope(endBlock, allAnalysis.isModified()); if (bodyAnalysis.isModified()) { diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 7c28e286f..dc60eee8c 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -4220,6 +4220,59 @@ private: "}"; values = tokenValues(code, "x . value"); ASSERT_EQUALS(0, values.size()); + + // #10166 + code = "int f(bool b) {\n" + " int x;\n" + " do {\n" + " if (b) {\n" + " x = 0;\n" + " break;\n" + " }\n" + " } while (true);\n" + " return x;\n" + "}\n"; + values = tokenValues(code, "x ; }", ValueFlow::Value::ValueType::UNINIT); + ASSERT_EQUALS(0, values.size()); + + code = "int f(bool b) {\n" + " int x;\n" + " while (true) {\n" + " if (b) {\n" + " x = 0;\n" + " break;\n" + " }\n" + " }\n" + " return x;\n" + "}\n"; + values = tokenValues(code, "x ; }", ValueFlow::Value::ValueType::UNINIT); + ASSERT_EQUALS(0, values.size()); + + code = "int f(bool b) {\n" + " int x;\n" + " for(;;) {\n" + " if (b) {\n" + " x = 0;\n" + " break;\n" + " }\n" + " }\n" + " return x;\n" + "}\n"; + values = tokenValues(code, "x ; }", ValueFlow::Value::ValueType::UNINIT); + ASSERT_EQUALS(0, values.size()); + + code = "int f(bool b) {\n" + " int x;\n" + " switch (b) {\n" + " case 1: {\n" + " ret = 0;\n" + " break;\n" + " }\n" + " }\n" + " return x;\n" + "}\n"; + values = tokenValues(code, "x ; }", ValueFlow::Value::ValueType::UNINIT); + ASSERT_EQUALS(0, values.size()); } void valueFlowConditionExpressions() {