Fixed #5223: Bailout in valueFlowForLoop1() for complex conditions

Refactorization: Reuse result instead of calling MathLib::toLongNumber() twice
This commit is contained in:
PKEuS 2014-12-30 19:56:47 +01:00
parent 5dc45bd4ac
commit 58f4660c94
2 changed files with 10 additions and 2 deletions

View File

@ -1312,13 +1312,13 @@ static bool valueFlowForLoop1(const Token *tok, unsigned int * const varid, Math
num2tok = tok->astOperand2(); num2tok = tok->astOperand2();
if (num2tok && num2tok->str() == "(" && !num2tok->astOperand2()) if (num2tok && num2tok->str() == "(" && !num2tok->astOperand2())
num2tok = num2tok->astOperand1(); num2tok = num2tok->astOperand1();
if (!Token::Match(num2tok, "%num%")) if (!Token::Match(num2tok, "%num% ;|%oror%")) // TODO: || enlarges the scope of the condition, so it should not cause FP, but it should no lnger be part of this pattern as soon as valueFlowForLoop2 can handle an unknown RHS of || better
num2tok = 0; num2tok = 0;
} }
if (!num2tok) if (!num2tok)
return false; return false;
*num2 = MathLib::toLongNumber(num2tok->str()) - ((tok->str()=="<=") ? 0 : 1); *num2 = MathLib::toLongNumber(num2tok->str()) - ((tok->str()=="<=") ? 0 : 1);
*numAfter = MathLib::toLongNumber(num2tok->str()) + ((tok->str()=="<=") ? 1 : 0); *numAfter = *num2 + 1;
if (!num1tok) if (!num1tok)
*num1 = *num2; *num1 = *num2;
while (tok && tok->str() != ";") while (tok && tok->str() != ";")

View File

@ -1196,6 +1196,14 @@ private:
"}"; "}";
ASSERT_EQUALS(false, testValueOfX(code, 4U, 0)); ASSERT_EQUALS(false, testValueOfX(code, 4U, 0));
code = "void f() {\n" // #5223
" for (int x = 0; x < 300 && x < 18; x++)\n"
" x;\n"
"}";
ASSERT_EQUALS(true, testValueOfX(code, 3U, 0));
ASSERT_EQUALS(true, testValueOfX(code, 3U, 17));
ASSERT_EQUALS(false, testValueOfX(code, 3U, 299));
code = "void f() {\n" code = "void f() {\n"
" int x;\n" " int x;\n"
" for (int i = 0; x = bar[i]; i++)\n" " for (int i = 0; x = bar[i]; i++)\n"