From fe80f858d16b223264a116733c79a628d57b46bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Tue, 22 Apr 2014 16:10:20 +0200 Subject: [PATCH] ValueFlow: Improved analysis in the valueFlowAfterAssign --- lib/valueflow.cpp | 19 ++++++++++++++++--- test/testvalueflow.cpp | 10 ++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 4ca41170f..87a4c0e9c 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -527,17 +527,30 @@ static void valueFlowAfterAssign(TokenList *tokenlist, ErrorLogger *errorLogger, continue; std::list values = tok->astOperand2()->values; + const bool constValue = tok->astOperand2()->isNumber(); + int indentlevel = 0; unsigned int number_of_if = 0; + int varusagelevel = -1; for (Token *tok2 = tok; tok2 && tok2 != endToken; tok2 = tok2->next()) { + if (indentlevel >= 0 && tok2->str() == "{") + ++indentlevel; + else if (indentlevel >= 0 && tok2->str() == "}") + --indentlevel; + if (Token::Match(tok2, "sizeof|typeof|typeid (")) tok2 = tok2->linkAt(1); // conditional block of code that assigns variable.. - if (Token::Match(tok2, "%var% (") && Token::simpleMatch(tok2->linkAt(1), ") {")) { + else if (Token::Match(tok2, "%var% (") && Token::simpleMatch(tok2->linkAt(1), ") {")) { Token * const start = tok2->linkAt(1)->next(); Token * const end = start->link(); - if (Token::findmatch(start, "%varid%", end, varid)) { + bool varusage = (indentlevel >= 0 && constValue && number_of_if == 0U) ? + isVariableChanged(start,end,varid) : + (nullptr != Token::findmatch(start, "%varid%", end, varid)); + if (varusage) { + varusagelevel = indentlevel; + // TODO: don't check noreturn scopes if (number_of_if > 0U || Token::findmatch(tok2, "%varid%", start, varid)) { if (settings->debugwarnings) @@ -586,7 +599,7 @@ static void valueFlowAfterAssign(TokenList *tokenlist, ErrorLogger *errorLogger, } } - else if (tok2->str() == "}") { + else if (tok2->str() == "}" && indentlevel == varusagelevel) { ++number_of_if; // Set "conditional" flag for all values diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 8f5a08795..16ca334be 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -594,6 +594,16 @@ private: "}"; TODO_ASSERT_EQUALS(true, false, testValueOfX(code, 4U, 32)); + code = "void f() {\n" + " int x = 32;\n" + " if (a==1) { z=x+12; }\n" + " if (a==2) { z=x+32; }\n" + " z = x;\n" + "}"; + ASSERT_EQUALS(true, testValueOfX(code, 3U, 32)); + ASSERT_EQUALS(true, testValueOfX(code, 4U, 32)); + ASSERT_EQUALS(true, testValueOfX(code, 5U, 32)); + code = "void f() {\n" // #5656 - FP " int x = 0;\n" " if (!x) {\n"