Refactorization: Use SymbolDatabase scope information in ValueFlow

This commit is contained in:
PKEuS 2015-02-01 12:10:20 +01:00
parent 54b6b8e571
commit a4cc4c3e3f
3 changed files with 368 additions and 360 deletions

View File

@ -1638,7 +1638,7 @@ bool Tokenizer::tokenize(std::istream &code,
}
list.createAst();
ValueFlow::setValues(&list, _errorLogger, _settings);
ValueFlow::setValues(&list, _symbolDatabase, _errorLogger, _settings);
}
return true;
@ -3854,7 +3854,7 @@ bool Tokenizer::simplifyTokenList2()
list.createAst();
ValueFlow::setValues(&list, _errorLogger, _settings);
ValueFlow::setValues(&list, _symbolDatabase, _errorLogger, _settings);
if (_settings->terminated())
return false;

View File

@ -421,9 +421,12 @@ static void valueFlowBitAnd(TokenList *tokenlist)
}
}
static void valueFlowBeforeCondition(TokenList *tokenlist, ErrorLogger *errorLogger, const Settings *settings)
static void valueFlowBeforeCondition(TokenList *tokenlist, SymbolDatabase *symboldatabase, ErrorLogger *errorLogger, const Settings *settings)
{
for (Token *tok = tokenlist->front(); tok; tok = tok->next()) {
const std::size_t functions = symboldatabase->functionScopes.size();
for (std::size_t i = 0; i < functions; ++i) {
const Scope * scope = symboldatabase->functionScopes[i];
for (Token* tok = const_cast<Token*>(scope->classStart); tok != scope->classEnd; tok = tok->next()) {
unsigned int varid=0;
MathLib::bigint num=0;
const Variable *var=0;
@ -515,7 +518,7 @@ static void valueFlowBeforeCondition(TokenList *tokenlist, ErrorLogger *errorLog
}
}
for (Token *tok2 = tok->previous(); ; tok2 = tok2->previous()) {
if (!tok2) {
if (!tok2 || tok2->next() == scope->classStart) {
if (settings->debugwarnings) {
std::list<ErrorLogger::ErrorMessage::FileLocation> callstack;
callstack.push_back(ErrorLogger::ErrorMessage::FileLocation(tok,tokenlist));
@ -650,6 +653,7 @@ static void valueFlowBeforeCondition(TokenList *tokenlist, ErrorLogger *errorLog
}
}
}
}
static void removeValues(std::list<ValueFlow::Value> &values, const std::list<ValueFlow::Value> &valuesToRemove)
{
@ -1010,21 +1014,22 @@ static bool valueFlowForward(Token * const startToken,
return true;
}
static void valueFlowAfterAssign(TokenList *tokenlist, ErrorLogger *errorLogger, const Settings *settings)
static void valueFlowAfterAssign(TokenList *tokenlist, SymbolDatabase* symboldatabase, ErrorLogger *errorLogger, const Settings *settings)
{
for (Token *tok = tokenlist->front(); tok; tok = tok->next()) {
const std::size_t functions = symboldatabase->functionScopes.size();
for (std::size_t i = 0; i < functions; ++i) {
const Scope * scope = symboldatabase->functionScopes[i];
for (Token* tok = const_cast<Token*>(scope->classStart); tok != scope->classEnd; tok = tok->next()) {
// Assignment
if ((tok->str() != "=") || (tok->astParent()))
continue;
// Lhs should be a variable
if (!tok->astOperand1() || !tok->astOperand1()->isName())
if (!tok->astOperand1() || !tok->astOperand1()->varId())
continue;
const unsigned int varid = tok->astOperand1()->varId();
if (varid == 0U)
continue;
const Variable *var = tok->astOperand1()->variable();
if (!var || !var->isLocal())
if (!var || (!var->isLocal() && !var->isArgument()))
continue;
const Token * const endOfVarScope = var->typeStartToken()->scope()->classEnd;
@ -1038,10 +1043,14 @@ static void valueFlowAfterAssign(TokenList *tokenlist, ErrorLogger *errorLogger,
valueFlowForward(tok, endOfVarScope, var, varid, values, constValue, tokenlist, errorLogger, settings);
}
}
}
static void valueFlowAfterCondition(TokenList *tokenlist, ErrorLogger *errorLogger, const Settings *settings)
static void valueFlowAfterCondition(TokenList *tokenlist, SymbolDatabase* symboldatabase, ErrorLogger *errorLogger, const Settings *settings)
{
for (Token *tok = tokenlist->front(); tok; tok = tok->next()) {
const std::size_t functions = symboldatabase->functionScopes.size();
for (std::size_t i = 0; i < functions; ++i) {
const Scope * scope = symboldatabase->functionScopes[i];
for (Token* tok = const_cast<Token*>(scope->classStart); tok != scope->classEnd; tok = tok->next()) {
const Token *vartok, *numtok;
// Comparison
@ -1188,6 +1197,7 @@ static void valueFlowAfterCondition(TokenList *tokenlist, ErrorLogger *errorLogg
}
}
}
}
static void execute(const Token *expr,
std::map<unsigned int, MathLib::bigint> * const programMemory,
@ -1512,17 +1522,14 @@ static void valueFlowForLoopSimplifyAfter(Token *fortok, unsigned int varid, con
settings);
}
static void valueFlowForLoop(TokenList *tokenlist, ErrorLogger *errorLogger, const Settings *settings)
static void valueFlowForLoop(TokenList *tokenlist, SymbolDatabase* symboldatabase, ErrorLogger *errorLogger, const Settings *settings)
{
for (Token *tok = tokenlist->front(); tok; tok = tok->next()) {
if (!Token::simpleMatch(tok, "for (") ||
!Token::simpleMatch(tok->next()->astOperand2(), ";") ||
!Token::simpleMatch(tok->next()->astOperand2()->astOperand2(), ";"))
for (std::list<Scope>::const_iterator scope = symboldatabase->scopeList.begin(); scope != symboldatabase->scopeList.end(); ++scope) {
if (scope->type != Scope::eFor)
continue;
Token * const bodyStart = tok->linkAt(1)->next();
if (!bodyStart || !bodyStart->link() || bodyStart->str() != "{")
continue;
Token* tok = const_cast<Token*>(scope->classDef);
Token* const bodyStart = const_cast<Token*>(scope->classStart);
unsigned int varid(0);
MathLib::bigint num1(0), num2(0), numAfter(0);
@ -1678,7 +1685,7 @@ static void valueFlowFunctionReturn(TokenList *tokenlist, ErrorLogger *errorLogg
}
}
void ValueFlow::setValues(TokenList *tokenlist, ErrorLogger *errorLogger, const Settings *settings)
void ValueFlow::setValues(TokenList *tokenlist, SymbolDatabase* symboldatabase, ErrorLogger *errorLogger, const Settings *settings)
{
for (Token *tok = tokenlist->front(); tok; tok = tok->next())
tok->values.clear();
@ -1688,9 +1695,9 @@ void ValueFlow::setValues(TokenList *tokenlist, ErrorLogger *errorLogger, const
valueFlowPointerAlias(tokenlist);
valueFlowFunctionReturn(tokenlist, errorLogger, settings);
valueFlowBitAnd(tokenlist);
valueFlowForLoop(tokenlist, errorLogger, settings);
valueFlowBeforeCondition(tokenlist, errorLogger, settings);
valueFlowAfterAssign(tokenlist, errorLogger, settings);
valueFlowAfterCondition(tokenlist, errorLogger, settings);
valueFlowForLoop(tokenlist, symboldatabase, errorLogger, settings);
valueFlowBeforeCondition(tokenlist, symboldatabase, errorLogger, settings);
valueFlowAfterAssign(tokenlist, symboldatabase, errorLogger, settings);
valueFlowAfterCondition(tokenlist, symboldatabase, errorLogger, settings);
valueFlowSubFunction(tokenlist, errorLogger, settings);
}

View File

@ -23,6 +23,7 @@
class Token;
class TokenList;
class SymbolDatabase;
class ErrorLogger;
class Settings;
@ -54,7 +55,7 @@ namespace ValueFlow {
bool inconclusive;
};
void setValues(TokenList *tokenlist, ErrorLogger *errorLogger, const Settings *settings);
void setValues(TokenList *tokenlist, SymbolDatabase* symboldatabase, ErrorLogger *errorLogger, const Settings *settings);
}
#endif // valueflowH