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;
}
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<ValueFlow::Value> values;
values.push_back(ValueFlow::Value(tok, numtok ? numtok->values.front().intvalue : 0LL));

View File

@ -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)