From a9c1a052b94a1e5051e075b398bf1632d651357a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 14 Sep 2012 19:13:44 +0200 Subject: [PATCH] CheckAssignIf: Improved checking for bitwise or --- lib/checkassignif.cpp | 14 ++++++-------- lib/checkassignif.h | 3 ++- test/testassignif.cpp | 12 ++++++++++++ 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/lib/checkassignif.cpp b/lib/checkassignif.cpp index e8bffdeef..8f61b74c2 100644 --- a/lib/checkassignif.cpp +++ b/lib/checkassignif.cpp @@ -85,10 +85,7 @@ void CheckAssignIf::comparison() return; for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { - if (tok->str() != "&") - continue; - - if (Token::Match(tok, "& %num% )| ==|!= %num% &&|%oror%|)")) { + if (Token::Match(tok, "&|%or% %num% )| ==|!= %num% &&|%oror%|)")) { const MathLib::bigint num1 = MathLib::toLongNumber(tok->strAt(1)); if (num1 < 0) continue; @@ -104,18 +101,19 @@ void CheckAssignIf::comparison() if (num2 < 0) continue; - if ((num1 & num2) != num2) { + if ((tok->str() == "&" && (num1 & num2) != num2) || + (tok->str() == "|" && (num1 | num2) != num2)) { const std::string& op(compareToken->str()); - comparisonError(tok, num1, op, num2, op=="==" ? false : true); + comparisonError(tok, tok->str(), num1, op, num2, op=="==" ? false : true); } } } } -void CheckAssignIf::comparisonError(const Token *tok, MathLib::bigint value1, const std::string &op, MathLib::bigint value2, bool result) +void CheckAssignIf::comparisonError(const Token *tok, const std::string &bitop, MathLib::bigint value1, const std::string &op, MathLib::bigint value2, bool result) { std::ostringstream expression; - expression << std::hex << "(X & 0x" << value1 << ") " << op << " 0x" << value2; + expression << std::hex << "(X " << bitop << " 0x" << value1 << ") " << op << " 0x" << value2; const std::string errmsg("Expression '" + expression.str() + "' is always " + (result?"true":"false") + ".\n" "The expression '" + expression.str() + "' is always " + (result?"true":"false") + diff --git a/lib/checkassignif.h b/lib/checkassignif.h index 82034f6cd..2d4c2242d 100644 --- a/lib/checkassignif.h +++ b/lib/checkassignif.h @@ -66,6 +66,7 @@ private: void assignIfError(const Token *tok, bool result); void comparisonError(const Token *tok, + const std::string &bitop, MathLib::bigint value1, const std::string &op, MathLib::bigint value2, @@ -76,7 +77,7 @@ private: void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const { CheckAssignIf c(0, settings, errorLogger); c.assignIfError(0, false); - c.comparisonError(0, 6, "==", 1, false); + c.comparisonError(0, "&", 6, "==", 1, false); c.multiConditionError(0,1); } diff --git a/test/testassignif.cpp b/test/testassignif.cpp index efb23aef0..5d485081b 100644 --- a/test/testassignif.cpp +++ b/test/testassignif.cpp @@ -106,6 +106,18 @@ private: " if (x & 4 != 3);\n" "}\n"); ASSERT_EQUALS("[test.cpp:3]: (style) Expression '(X & 0x4) != 0x3' is always true.\n", errout.str()); + + check("void foo(int x)\n" + "{\n" + " if ((x | 4) == 3);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:3]: (style) Expression '(X | 0x4) == 0x3' is always false.\n", errout.str()); + + check("void foo(int x)\n" + "{\n" + " if ((x | 4) != 3);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:3]: (style) Expression '(X | 0x4) != 0x3' is always true.\n", errout.str()); } void multicompare() {