From f908959196e2cd6b95481588cd41298185eda4ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 1 Aug 2014 16:12:57 +0200 Subject: [PATCH] ValueFlow: improved analysis in for loops to avoid fp --- lib/valueflow.cpp | 17 +++++++++++++++++ test/testvalueflow.cpp | 20 ++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index bbd3271c2..817104488 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -1208,6 +1208,23 @@ static void valueFlowForLoopSimplify(Token * const bodyStart, const unsigned int setTokenValue(tok2, value1); } + if (Token::Match(tok2, "%oror%|&&")) { + const std::map programMemory(getProgramMemory(tok2->astTop(), varid, value)); + if ((tok2->str() == "&&" && conditionIsFalse(tok2->astOperand1(), programMemory)) || + (tok2->str() == "||" && conditionIsTrue(tok2->astOperand1(), programMemory))) { + // Skip second expression.. + const Token *parent = tok2; + while (parent && parent->str() == tok2->str()) + parent = parent->astParent(); + if (parent && parent->str() == "(") + tok2 = parent->link(); + } + + } + if ((tok2->str() == "&&" && conditionIsFalse(tok2->astOperand1(), getProgramMemory(tok2->astTop(), varid, value))) || + (tok2->str() == "||" && conditionIsTrue(tok2->astOperand1(), getProgramMemory(tok2->astTop(), varid, value)))) + break; + else if (Token::simpleMatch(tok2, ") {") && Token::findmatch(tok2->link(), "%varid%", tok2, varid)) { if (Token::findmatch(tok2, "continue|break|return", tok2->linkAt(1), varid)) { if (settings->debugwarnings) diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 6242675b6..bfe3a6145 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -962,6 +962,26 @@ private: " }\n" "}\n"; ASSERT_EQUALS(false, testValueOfX(code, 3U, 0)); + + // && + code = "void foo() {\n" + " for (int x = 0; x < 10; x++) {\n" + " if (x > 1\n" + " && x) {}" // <- x is not 0 + " }\n" + "}\n"; + ASSERT_EQUALS(false, testValueOfX(code, 4U, 0)); + ASSERT_EQUALS(true, testValueOfX(code, 4U, 9)); + + // || + code = "void foo() {\n" + " for (int x = 0; x < 10; x++) {\n" + " if (x == 0\n" + " || x) {}" // <- x is not 0 + " }\n" + "}\n"; + ASSERT_EQUALS(false, testValueOfX(code, 4U, 0)); + ASSERT_EQUALS(true, testValueOfX(code, 4U, 9)); } void valueFlowSubFunction() {