Implement #7597 - valueflow: global constant (#1802)

* Implement const global value flow

* Tabs to spaces
This commit is contained in:
Gary Leutheuser 2019-04-21 00:54:32 -04:00 committed by Daniel Marjamäki
parent e786c6b7d4
commit bca2dfb3f4
2 changed files with 46 additions and 0 deletions

View File

@ -1458,6 +1458,39 @@ static void valueFlowOppositeCondition(SymbolDatabase *symboldatabase, const Set
}
}
static void valueFlowGlobalConstVar(TokenList* tokenList, const Settings *settings)
{
// Get variable values...
std::map<const Variable*, ValueFlow::Value> vars;
for (const Token* tok = tokenList->front(); tok; tok = tok->next()) {
if (!tok->variable())
continue;
// Initialization...
if (tok == tok->variable()->nameToken() &&
!tok->variable()->isStatic() &&
tok->variable()->isConst() &&
tok->valueType() &&
tok->valueType()->isIntegral() &&
tok->valueType()->pointer == 0 &&
tok->valueType()->constness == 1 &&
Token::Match(tok, "%name% =") &&
tok->next()->astOperand2() &&
tok->next()->astOperand2()->hasKnownIntValue()) {
vars[tok->variable()] = tok->next()->astOperand2()->values().front();
}
}
// Set values..
for (Token* tok = tokenList->front(); tok; tok = tok->next()) {
if (!tok->variable())
continue;
std::map<const Variable*, ValueFlow::Value>::const_iterator var = vars.find(tok->variable());
if (var == vars.end())
continue;
setTokenValue(tok, var->second, settings);
}
}
static void valueFlowGlobalStaticVar(TokenList *tokenList, const Settings *settings)
{
// Get variable values...
@ -5241,6 +5274,7 @@ void ValueFlow::setValues(TokenList *tokenlist, SymbolDatabase* symboldatabase,
valueFlowNumber(tokenlist);
valueFlowString(tokenlist);
valueFlowArray(tokenlist);
valueFlowGlobalConstVar(tokenlist, settings);
valueFlowGlobalStaticVar(tokenlist, settings);
valueFlowPointerAlias(tokenlist);
valueFlowLifetime(tokenlist, symboldatabase, errorLogger, settings);

View File

@ -103,6 +103,8 @@ private:
TEST_CASE(valueFlowGlobalVar);
TEST_CASE(valueFlowGlobalConstVar);
TEST_CASE(valueFlowGlobalStaticVar);
TEST_CASE(valueFlowInlineAssembly);
@ -3165,6 +3167,16 @@ private:
ASSERT_EQUALS(false, testValueOfX(code, 5U, 42));
}
void valueFlowGlobalConstVar() {
const char* code;
code = "const int x = 321;\n"
"void f() {\n"
" a = x;\n"
"}";
ASSERT_EQUALS(true, testValueOfX(code, 3U, 321));
}
void valueFlowGlobalStaticVar() {
const char *code;