Fixed #6022: Support ++%var% in valueFlowForLoop1
Fixed TODO unit test: properly handle loops that are never executed
This commit is contained in:
parent
9e8a66ee40
commit
ec826a0e0e
|
@ -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)) {
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue