diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 36ced86c7..791954e98 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -2573,6 +2573,41 @@ void CheckOther::assignBoolToPointerError(const Token *tok) "Assigning bool value to pointer (converting bool value to address)"); } +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +void CheckOther::checkComparisonOfBoolExpressionWithInt() +{ + for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) + { + if (Token::Match(tok, "&&|%oror% %any% ) ==|!=|>|< %num%")) + { + const std::string& op = tok->strAt(3); + const std::string& num = tok->strAt(4); + if ((op == "<" || num != "0") && (op == ">" || num != "1")) + { + comparisonOfBoolExpressionWithIntError(tok->next()); + } + } + + else if (Token::Match(tok, "%num% ==|!=|>|< ( %any% &&|%oror%")) + { + const std::string& op = tok->strAt(1); + const std::string& num = tok->str(); + if ((op == ">" || num != "0") && (op == "<" || num != "1")) + { + comparisonOfBoolExpressionWithIntError(tok->next()); + } + } + } +} + +void CheckOther::comparisonOfBoolExpressionWithIntError(const Token *tok) +{ + reportError(tok, Severity::warning, "compareBoolExpressionWithInt", + "Comparison of a boolean expression with an integer other than 0 or 1."); +} + + //--------------------------------------------------------------------------- // Check testing sign of unsigned variables. //--------------------------------------------------------------------------- diff --git a/lib/checkother.h b/lib/checkother.h index 0af0d96c9..47c9e940a 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -71,6 +71,7 @@ public: checkOther.checkVariableScope(); checkOther.clarifyCondition(); // not simplified because ifAssign + checkOther.checkComparisonOfBoolExpressionWithInt(); } /** @brief Run checks against the simplified token list */ @@ -229,6 +230,9 @@ public: /** @brief %Check for using bool in bitwise expression */ void checkBitwiseOnBoolean(); + /** @brief %Check for comparing a bool expression with an integer other than 0 or 1 */ + void checkComparisonOfBoolExpressionWithInt(); + // Error messages.. void cstyleCastError(const Token *tok); void dangerousUsageStrtolError(const Token *tok); @@ -266,6 +270,7 @@ public: void unsignedLessThanZeroError(const Token *tok, const std::string &varname); void unsignedPositiveError(const Token *tok, const std::string &varname); void bitwiseOnBooleanError(const Token *tok, const std::string &varname, const std::string &op); + void comparisonOfBoolExpressionWithIntError(const Token *tok); void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) { @@ -315,6 +320,7 @@ public: c.unsignedLessThanZeroError(0, "varname"); c.unsignedPositiveError(0, "varname"); c.bitwiseOnBooleanError(0, "varname", "&&"); + c.comparisonOfBoolExpressionWithIntError(0); } std::string myName() const @@ -358,6 +364,7 @@ public: "* Clarify calculation with parentheses\n" "* using increment on boolean\n" "* comparison of a boolean with a non-zero integer\n" + "* comparison of a boolean expression with an integer other than 0 or 1\n" "* suspicious condition (assignment+comparison)\n" "* suspicious condition (runtime comparison of string literals)\n" "* duplicate break statement\n" diff --git a/test/testother.cpp b/test/testother.cpp index 780c71f80..1c8eb7616 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -123,6 +123,8 @@ private: TEST_CASE(clarifyCondition4); // ticket #3110 TEST_CASE(bitwiseOnBoolean); // if (bool & bool) + TEST_CASE(comparisonOfBoolExpressionWithInt); + TEST_CASE(incorrectStringCompare); TEST_CASE(incrementBoolean); @@ -167,6 +169,7 @@ private: checkOther.checkDuplicateBranch(); checkOther.checkDuplicateExpression(); checkOther.checkBitwiseOnBoolean(); + checkOther.checkComparisonOfBoolExpressionWithInt(); // Simplify token list.. tokenizer.simplifyTokenList(); @@ -2464,6 +2467,142 @@ private: ASSERT_EQUALS("", errout.str()); } + + void comparisonOfBoolExpressionWithInt() + { + check("void f(int x) {\n" + " if ((x && 0x0f)==6)\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean expression with an integer other than 0 or 1.\n", errout.str()); + + check("void f(int x) {\n" + " if ((x && 0x0f)==0)\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("", errout.str()); + + check("void f(int x) {\n" + " if ((x || 0x0f)==6)\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean expression with an integer other than 0 or 1.\n", errout.str()); + + check("void f(int x) {\n" + " if ((x || 0x0f)==0)\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("", errout.str()); + + check("void f(int x) {\n" + " if ((x & 0x0f)==6)\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("", errout.str()); + + check("void f(int x) {\n" + " if ((x | 0x0f)==6)\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("", errout.str()); + + + check("void f(int x) {\n" + " if ((5 && x)==3)\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean expression with an integer other than 0 or 1.\n", errout.str()); + + check("void f(int x) {\n" + " if ((5 && x)==3 || (8 && x)==9)\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean expression with an integer other than 0 or 1.\n", errout.str()); + + check("void f(int x) {\n" + " if ((5 && x)!=3)\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean expression with an integer other than 0 or 1.\n", errout.str()); + + + check("void f(int x) {\n" + " if ((5 && x) > 3)\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean expression with an integer other than 0 or 1.\n", errout.str()); + + check("void f(int x) {\n" + " if ((5 && x) > 0)\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("", errout.str()); + + check("void f(int x) {\n" + " if ((5 && x) < 0)\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean expression with an integer other than 0 or 1.\n", errout.str()); + + check("void f(int x) {\n" + " if ((5 && x) < 1)\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("", errout.str()); + + check("void f(int x) {\n" + " if ((5 && x) > 1)\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean expression with an integer other than 0 or 1.\n", errout.str()); + + + check("void f(int x) {\n" + " if (0 < (5 && x))\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("", errout.str()); + + check("void f(int x) {\n" + " if (0 > (5 && x))\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean expression with an integer other than 0 or 1.\n", errout.str()); + + check("void f(int x) {\n" + " if (1 > (5 && x))\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("", errout.str()); + + check("void f(int x) {\n" + " if (1 < (5 && x))\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean expression with an integer other than 0 or 1.\n", errout.str()); + + + } + + void catchExceptionByValue() { check("void f() {\n"