diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index ed83336d5..9d633f852 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -1327,6 +1327,10 @@ static bool valueFlowForward(Token * const startToken, continue; } + else if (var->isGlobal() && Token::Match(tok2, "%name% (") && Token::Match(tok2->linkAt(1), ") !!{")) { + return false; + } + if (Token::Match(tok2, "sizeof|typeof|typeid (")) tok2 = tok2->linkAt(1); @@ -1653,9 +1657,7 @@ static bool valueFlowForward(Token * const startToken, tok2 = tok2->next(); } - if (!tok2) // invalid code #7236 - return false; - if (tok2->varId() == varid) { + else if (tok2->varId() == varid) { // bailout: assignment if (Token::Match(tok2->previous(), "!!* %name% %op%") && tok2->next()->isAssignmentOp()) { // simplify rhs @@ -1967,7 +1969,7 @@ static void valueFlowAfterAssign(TokenList *tokenlist, SymbolDatabase* symboldat if (aliased.find(varid) != aliased.end()) continue; const Variable *var = tok->astOperand1()->variable(); - if (!var || (!var->isLocal() && !var->isArgument())) + if (!var || (!var->isLocal() && !var->isGlobal() && !var->isArgument())) continue; const Token * const endOfVarScope = var->typeStartToken()->scope()->classEnd; @@ -2047,7 +2049,7 @@ static void valueFlowAfterCondition(TokenList *tokenlist, SymbolDatabase* symbol if (varid == 0U) continue; const Variable *var = vartok->variable(); - if (!var || !(var->isLocal() || var->isArgument())) + if (!var || !(var->isLocal() || var->isGlobal() || var->isArgument())) continue; std::list values; values.push_back(ValueFlow::Value(tok, numtok ? numtok->values.front().intvalue : 0LL)); diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 7b403bc6c..7545a0412 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -80,6 +80,8 @@ private: TEST_CASE(knownValue); TEST_CASE(valueFlowSizeofForwardDeclaredEnum); + + TEST_CASE(valueFlowGlobalVar); } bool testValueOfX(const char code[], unsigned int linenr, int value) { @@ -2308,6 +2310,32 @@ private: const char *code = "enum E; sz=sizeof(E);"; valueOfTok(code, "="); // Don't crash (#7775) } + + void valueFlowGlobalVar() { + const char *code; + + code = "int x;\n" + "void f() {\n" + " x = 4;\n" + " a = x;\n" + "}"; + ASSERT_EQUALS(true, testValueOfX(code, 4U, 4)); + + code = "int x;\n" + "void f() {\n" + " if (x == 4) {}\n" + " a = x;\n" + "}"; + ASSERT_EQUALS(true, testValueOfX(code, 4U, 4)); + + code = "int x;\n" + "void f() {\n" + " x = 42;\n" + " unknownFunction();\n" + " a = x;\n" + "}"; + ASSERT_EQUALS(false, testValueOfX(code, 5U, 42)); + } }; REGISTER_TEST(TestValueFlow)