ValueFlow: Handle enums

This commit is contained in:
Daniel Marjamäki 2016-05-07 20:18:07 +02:00
parent ad2d3394c8
commit b26dd1ccab
3 changed files with 40 additions and 9 deletions

View File

@ -570,14 +570,28 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value)
}
}
// Handle various constants..
static void valueFlowSetConstantValue(const Token *tok)
{
if ((tok->isNumber() && MathLib::isInt(tok->str())) || (tok->tokType() == Token::eChar)) {
ValueFlow::Value value(MathLib::toLongNumber(tok->str()));
value.setKnown();
setTokenValue(const_cast<Token *>(tok), value);
}
if (tok->enumerator() && tok->enumerator()->value_known) {
ValueFlow::Value value(tok->enumerator()->value);
value.setKnown();
setTokenValue(const_cast<Token *>(tok), value);
}
}
static void valueFlowNumber(TokenList *tokenlist)
{
for (Token *tok = tokenlist->front(); tok; tok = tok->next()) {
if ((tok->isNumber() && MathLib::isInt(tok->str())) || (tok->tokType() == Token::eChar)) {
ValueFlow::Value value(MathLib::toLongNumber(tok->str()));
value.setKnown();
setTokenValue(tok, value);
}
valueFlowSetConstantValue(tok);
}
if (tokenlist->isCPP()) {
@ -2363,6 +2377,16 @@ static void valueFlowFunctionReturn(TokenList *tokenlist, ErrorLogger *errorLogg
}
}
void ValueFlow::valueFlowConstantFoldAST(const Token *expr)
{
if (!expr || !expr->values.empty())
return;
valueFlowConstantFoldAST(expr->astOperand1());
valueFlowConstantFoldAST(expr->astOperand2());
valueFlowSetConstantValue(expr);
}
void ValueFlow::setValues(TokenList *tokenlist, SymbolDatabase* symboldatabase, ErrorLogger *errorLogger, const Settings *settings)
{
for (Token *tok = tokenlist->front(); tok; tok = tok->next())
@ -2400,3 +2424,5 @@ std::string ValueFlow::eitherTheConditionIsRedundant(const Token *condition)
}
return "Either the condition '" + condition->expressionString() + "' is redundant";
}

View File

@ -94,6 +94,10 @@ namespace ValueFlow {
}
};
/// Constant folding of expression. This can be used before the full ValueFlow has been executed (ValueFlow::setValues).
void valueFlowConstantFoldAST(const Token *expr);
/// Perform valueflow analysis.
void setValues(TokenList *tokenlist, SymbolDatabase* symboldatabase, ErrorLogger *errorLogger, const Settings *settings);
std::string eitherTheConditionIsRedundant(const Token *condition);

View File

@ -164,11 +164,12 @@ private:
}
void valueFlowNumber() {
ASSERT_EQUALS(123, valueOfTok("x=123;", "123").intvalue);
ASSERT_EQUALS(123, valueOfTok("x=123;", "123").intvalue);
ASSERT_EQUALS(10, valueOfTok("enum {A=10,B=15}; x=A+0;", "+").intvalue);
ASSERT_EQUALS(0, valueOfTok("x=false;", "false").intvalue);
ASSERT_EQUALS(1, valueOfTok("x=true;", "true").intvalue);
ASSERT_EQUALS(0, valueOfTok("x(NULL);", "NULL").intvalue);
ASSERT_EQUALS((int)('a'), valueOfTok("x='a';", "'a'").intvalue);
ASSERT_EQUALS(1, valueOfTok("x=true;", "true").intvalue);
ASSERT_EQUALS(0, valueOfTok("x(NULL);", "NULL").intvalue);
ASSERT_EQUALS((int)('a'), valueOfTok("x='a';", "'a'").intvalue);
ASSERT_EQUALS((int)('\n'), valueOfTok("x='\\n';", "'\\n'").intvalue);
}