From 58f4660c94a4bc2c11f19cee644426203e9f3866 Mon Sep 17 00:00:00 2001 From: PKEuS Date: Tue, 30 Dec 2014 19:56:47 +0100 Subject: [PATCH] Fixed #5223: Bailout in valueFlowForLoop1() for complex conditions Refactorization: Reuse result instead of calling MathLib::toLongNumber() twice --- lib/valueflow.cpp | 4 ++-- test/testvalueflow.cpp | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index c8cf01002..286b65566 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -1312,13 +1312,13 @@ static bool valueFlowForLoop1(const Token *tok, unsigned int * const varid, Math num2tok = tok->astOperand2(); if (num2tok && num2tok->str() == "(" && !num2tok->astOperand2()) 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; } if (!num2tok) return false; *num2 = MathLib::toLongNumber(num2tok->str()) - ((tok->str()=="<=") ? 0 : 1); - *numAfter = MathLib::toLongNumber(num2tok->str()) + ((tok->str()=="<=") ? 1 : 0); + *numAfter = *num2 + 1; if (!num1tok) *num1 = *num2; while (tok && tok->str() != ";") diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 309a55732..6a615da33 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -1196,6 +1196,14 @@ private: "}"; 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" " int x;\n" " for (int i = 0; x = bar[i]; i++)\n"