From ec826a0e0e4e64dcbb58717f8c654d87000d956f Mon Sep 17 00:00:00 2001 From: PKEuS Date: Tue, 30 Dec 2014 18:50:22 +0100 Subject: [PATCH] Fixed #6022: Support ++%var% in valueFlowForLoop1 Fixed TODO unit test: properly handle loops that are never executed --- lib/valueflow.cpp | 15 ++++++++------- test/testvalueflow.cpp | 18 ++++++++++++++---- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 3819449f3..c8cf01002 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -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 mem1, mem2, memAfter; if (valueFlowForLoop2(tok, &mem1, &mem2, &memAfter)) { diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 2300daa17..309a55732 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -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"