Fixed #6022: Support ++%var% in valueFlowForLoop1

Fixed TODO unit test: properly handle loops that are never executed
This commit is contained in:
PKEuS 2014-12-30 18:50:22 +01:00
parent 9e8a66ee40
commit ec826a0e0e
2 changed files with 22 additions and 11 deletions

View File

@ -1291,7 +1291,7 @@ static void execute(const Token *expr,
static bool valueFlowForLoop1(const Token *tok, unsigned int * const varid, MathLib::bigint * const num1, MathLib::bigint * const num2, MathLib::bigint * const numAfter)
{
tok = tok->tokAt(2);
if (!Token::Match(tok,"%type%| %var% ="))
if (!Token::Match(tok, "%type%| %var% ="))
return false;
const Token * const vartok = Token::Match(tok, "%var% =") ? tok : tok->next();
if (vartok->varId() == 0U)
@ -1323,7 +1323,7 @@ static bool valueFlowForLoop1(const Token *tok, unsigned int * const varid, Math
*num1 = *num2;
while (tok && tok->str() != ";")
tok = tok->next();
if (!Token::Match(tok, "; %varid% ++ ) {", vartok->varId()))
if (!Token::Match(tok, "; %varid% ++ ) {", vartok->varId()) && !Token::Match(tok, "; ++ %varid% ) {", vartok->varId()))
return false;
return true;
}
@ -1507,11 +1507,12 @@ static void valueFlowForLoop(TokenList *tokenlist, ErrorLogger *errorLogger, con
MathLib::bigint num1(0), num2(0), numAfter(0);
if (valueFlowForLoop1(tok, &varid, &num1, &num2, &numAfter)) {
if (num1 > num2)
continue;
valueFlowForLoopSimplify(bodyStart, varid, num1, tokenlist, errorLogger, settings);
valueFlowForLoopSimplify(bodyStart, varid, num2, tokenlist, errorLogger, settings);
valueFlowForLoopSimplifyAfter(tok, varid, numAfter, tokenlist, errorLogger, settings);
if (num1 <= num2) {
valueFlowForLoopSimplify(bodyStart, varid, num1, tokenlist, errorLogger, settings);
valueFlowForLoopSimplify(bodyStart, varid, num2, tokenlist, errorLogger, settings);
valueFlowForLoopSimplifyAfter(tok, varid, numAfter, tokenlist, errorLogger, settings);
} else
valueFlowForLoopSimplifyAfter(tok, varid, num1, tokenlist, errorLogger, settings);
} else {
std::map<unsigned int, MathLib::bigint> mem1, mem2, memAfter;
if (valueFlowForLoop2(tok, &mem1, &mem2, &memAfter)) {

View File

@ -1143,12 +1143,22 @@ private:
ASSERT_EQUALS(false, testValueOfX(code, 3U, 10));
code = "void f() {\n"
" for (int x = 2; x < 1; x++)\n"
" int x;\n"
" for (x = 2; x < 1; x++)\n"
" a[x] = 0;\n" // <- not 2
" b = x;\n" // <- TODO: this is 2
" b = x;\n" // 2
"}";
ASSERT_EQUALS(false, testValueOfX(code, 3U, 2));
TODO_ASSERT_EQUALS(true, false, testValueOfX(code, 4U, 2));
ASSERT_EQUALS(false, testValueOfX(code, 4U, 2));
ASSERT_EQUALS(true, testValueOfX(code, 5U, 2));
code = "void f() {\n"
" int x;\n"
" for (x = 2; x < 1; ++x)\n"
" a[x] = 0;\n" // <- not 2
" b = x;\n" // 2
"}";
ASSERT_EQUALS(false, testValueOfX(code, 4U, 2));
ASSERT_EQUALS(true, testValueOfX(code, 5U, 2));
code = "void f(int a) {\n"
" for (int x = a; x < 10; x++)\n"