Fixed #7323 (valueflow: global variables)

This commit is contained in:
Daniel Marjamäki 2017-01-09 15:53:08 +01:00
parent 24996300a5
commit b1f7e46491
2 changed files with 35 additions and 5 deletions

View File

@ -1327,6 +1327,10 @@ static bool valueFlowForward(Token * const startToken,
continue; continue;
} }
else if (var->isGlobal() && Token::Match(tok2, "%name% (") && Token::Match(tok2->linkAt(1), ") !!{")) {
return false;
}
if (Token::Match(tok2, "sizeof|typeof|typeid (")) if (Token::Match(tok2, "sizeof|typeof|typeid ("))
tok2 = tok2->linkAt(1); tok2 = tok2->linkAt(1);
@ -1653,9 +1657,7 @@ static bool valueFlowForward(Token * const startToken,
tok2 = tok2->next(); tok2 = tok2->next();
} }
if (!tok2) // invalid code #7236 else if (tok2->varId() == varid) {
return false;
if (tok2->varId() == varid) {
// bailout: assignment // bailout: assignment
if (Token::Match(tok2->previous(), "!!* %name% %op%") && tok2->next()->isAssignmentOp()) { if (Token::Match(tok2->previous(), "!!* %name% %op%") && tok2->next()->isAssignmentOp()) {
// simplify rhs // simplify rhs
@ -1967,7 +1969,7 @@ static void valueFlowAfterAssign(TokenList *tokenlist, SymbolDatabase* symboldat
if (aliased.find(varid) != aliased.end()) if (aliased.find(varid) != aliased.end())
continue; continue;
const Variable *var = tok->astOperand1()->variable(); const Variable *var = tok->astOperand1()->variable();
if (!var || (!var->isLocal() && !var->isArgument())) if (!var || (!var->isLocal() && !var->isGlobal() && !var->isArgument()))
continue; continue;
const Token * const endOfVarScope = var->typeStartToken()->scope()->classEnd; const Token * const endOfVarScope = var->typeStartToken()->scope()->classEnd;
@ -2047,7 +2049,7 @@ static void valueFlowAfterCondition(TokenList *tokenlist, SymbolDatabase* symbol
if (varid == 0U) if (varid == 0U)
continue; continue;
const Variable *var = vartok->variable(); const Variable *var = vartok->variable();
if (!var || !(var->isLocal() || var->isArgument())) if (!var || !(var->isLocal() || var->isGlobal() || var->isArgument()))
continue; continue;
std::list<ValueFlow::Value> values; std::list<ValueFlow::Value> values;
values.push_back(ValueFlow::Value(tok, numtok ? numtok->values.front().intvalue : 0LL)); values.push_back(ValueFlow::Value(tok, numtok ? numtok->values.front().intvalue : 0LL));

View File

@ -80,6 +80,8 @@ private:
TEST_CASE(knownValue); TEST_CASE(knownValue);
TEST_CASE(valueFlowSizeofForwardDeclaredEnum); TEST_CASE(valueFlowSizeofForwardDeclaredEnum);
TEST_CASE(valueFlowGlobalVar);
} }
bool testValueOfX(const char code[], unsigned int linenr, int value) { bool testValueOfX(const char code[], unsigned int linenr, int value) {
@ -2308,6 +2310,32 @@ private:
const char *code = "enum E; sz=sizeof(E);"; const char *code = "enum E; sz=sizeof(E);";
valueOfTok(code, "="); // Don't crash (#7775) 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) REGISTER_TEST(TestValueFlow)