diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index c322ee565..a1900f2e5 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -687,7 +687,7 @@ static void compileExpression(Token *&tok, std::stack &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 operands; compileExpression(tok, operands); } diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 20d44487c..fc0cfe8f9 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -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 diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 39b86b660..da14d41a1 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -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));