value flow: improved handling of for loops

This commit is contained in:
Daniel Marjamäki 2014-01-10 18:18:49 +01:00
parent 3eebc8a9f1
commit c687933e9f
3 changed files with 21 additions and 5 deletions

View File

@ -687,7 +687,7 @@ static void compileExpression(Token *&tok, std::stack<Token*> &op)
void TokenList::createAst()
{
for (Token *tok = _front; tok; tok = tok ? tok->next() : NULL) {
if (tok->str() == "return" || !tok->previous() || Token::Match(tok, "%var% (|[|.|=|::") || Token::Match(tok->previous(), "[;{}] %cop%")) {
if (tok->str() == "return" || !tok->previous() || Token::Match(tok, "%var% %op%|(|[|.|=|::") || Token::Match(tok->previous(), "[;{}] %cop%")) {
std::stack<Token *> operands;
compileExpression(tok, operands);
}

View File

@ -165,14 +165,30 @@ static void valueFlowForLoop(TokenList *tokenlist, ErrorLogger *errorLogger, con
if (vartok->varId() == 0U)
continue;
tok = vartok->tokAt(4);
if (!Token::Match(tok, "%varid% <|<=|!= %num% ; %varid% ++ ) {", vartok->varId())) {
const Token *num2tok = 0;
if (Token::Match(tok, "%varid% <|<=|!=", vartok->varId())) {
tok = tok->next();
num2tok = tok->astOperand2();
if (num2tok && num2tok->str() == "(" && !num2tok->astOperand2())
num2tok = num2tok->astOperand1();
if (!Token::Match(num2tok, "%num%"))
num2tok = 0;
}
if (!num2tok) {
if (settings->debugwarnings)
bailout(tokenlist, errorLogger, tok, "For loop not handled");
continue;
}
const MathLib::bigint num2 = MathLib::toLongNumber(num2tok ? num2tok->str() : "0") - ((tok->str()=="<=") ? 0 : 1);
while (tok && tok->str() != ";")
tok = tok->next();
if (!num2tok || !Token::Match(tok, "; %varid% ++ ) {", vartok->varId())) {
if (settings->debugwarnings)
bailout(tokenlist, errorLogger, tok, "For loop not handled");
continue;
}
const MathLib::bigint num2 = MathLib::toLongNumber(tok->strAt(2)) - ((tok->strAt(1)=="<=") ? 0 : 1);
Token * const bodyStart = tok->tokAt(7);
Token * const bodyStart = tok->tokAt(4);
const Token * const bodyEnd = bodyStart->link();
// Is variable modified inside for loop

View File

@ -165,7 +165,7 @@ private:
ASSERT_EQUALS(false, testValueOfX(code, 3U, 10));
code = "void f() {\n"
" for (int x = 0; x < (short)10; x++)\n"
" for (int x = 0; x < ((short)10); x++)\n"
" a[x] = 0;\n"
"}";
ASSERT_EQUALS(true, testValueOfX(code, 3U, 0));