Refactoring valueFlowSubFunction

This commit is contained in:
Daniel Marjamäki 2014-08-06 06:33:06 +02:00
parent 4894d3807d
commit 8bbbb54f94
1 changed files with 48 additions and 51 deletions

View File

@ -1325,17 +1325,34 @@ static void valueFlowForLoop(TokenList *tokenlist, ErrorLogger *errorLogger, con
static void valueFlowSubFunction(TokenList *tokenlist, ErrorLogger *errorLogger, const Settings *settings)
{
std::list<ValueFlow::Value> argvalues;
for (Token *tok = tokenlist->front(); tok; tok = tok->next()) {
if (!Token::Match(tok, "[(,]"))
if (!Token::Match(tok, "%var% ("))
continue;
const Function * const currentFunction = tok->function();
if (!currentFunction)
continue;
// Function scope..
const Scope * const functionScope = currentFunction->functionScope;
if (!functionScope)
continue;
unsigned int argnr = 0U;
for (const Token *argtok = tok->tokAt(2); argtok; argtok = argtok->nextArgument()) {
// Get function argument
const Variable * const arg = currentFunction->getArgumentVar(argnr++);
if (!arg)
break;
std::list<ValueFlow::Value> argvalues;
// passing value(s) to function
if (Token::Match(tok, "[(,] %var%|%num%|%str% [,)]") && !tok->next()->values.empty())
argvalues = tok->next()->values;
if (Token::Match(argtok, "%var%|%num%|%str% [,)]") && !argtok->values.empty())
argvalues = argtok->values;
else {
// bool operator => values 1/0 are passed to function..
const Token *op = tok->next();
const Token *op = argtok;
while (op && op->astParent() && !Token::Match(op->astParent(), "[(,]"))
op = op->astParent();
if (Token::Match(op, "%comp%|%oror%|&&|!")) {
@ -1350,30 +1367,9 @@ static void valueFlowSubFunction(TokenList *tokenlist, ErrorLogger *errorLogger,
}
}
const Token * const argumentToken = tok->next();
// is this a function call?
const Token *ftok = tok;
while (ftok && ftok->str() != "(")
ftok = ftok->astParent();
if (!ftok || !ftok->astOperand1() || !ftok->astOperand2() || !ftok->astOperand1()->function())
continue;
// Get argument nr
unsigned int argnr = 0;
for (const Token *argtok = ftok->next(); argtok && argtok != argumentToken; argtok = argtok->nextArgument())
++ argnr;
// Get function argument, and check if parameter is passed by value
const Function * const function = ftok->astOperand1()->function();
const Variable * const arg = function ? function->getArgumentVar(argnr) : nullptr;
if (!Token::Match(arg ? arg->typeStartToken() : nullptr, "%type% %var% ,|)") &&
!Token::Match(arg ? arg->typeStartToken() : nullptr, "const| struct| %type% * %var% ,|)"))
continue;
// Function scope..
const Scope * const functionScope = function ? function->functionScope : nullptr;
if (!functionScope)
// Is argument passed by value?
if (!Token::Match(arg->typeStartToken(), "%type% %var% ,|)") &&
!Token::Match(arg->typeStartToken(), "const| struct| %type% * %var% ,|)"))
continue;
// Set value in function scope..
@ -1390,6 +1386,7 @@ static void valueFlowSubFunction(TokenList *tokenlist, ErrorLogger *errorLogger,
}
}
}
}
static bool constval(const Token * tok)
{