diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 33a869b5f..2c25e02c2 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1341,10 +1341,14 @@ void CheckOther::checkComparisonOfBoolWithInt() } else if (tok->isBoolean() && right->varId()) { // Comparing boolean constant with variable if (isNonBoolStdType(symbolDatabase->getVariableFromVarId(right->varId()))) { // Variable has to be of non-boolean standard type comparisonOfBoolWithIntError(right, tok->str(), false); + } else if (tok->strAt(1) != "==" && tok->strAt(1) != "!=") { + comparisonOfBoolWithInvalidComparator(right, tok->str()); } } else if (tok->varId() && right->isBoolean()) { // Comparing variable with boolean constant if (isNonBoolStdType(symbolDatabase->getVariableFromVarId(tok->varId()))) { // Variable has to be of non-boolean standard type comparisonOfBoolWithIntError(tok, right->str(), false); + } else if (tok->strAt(1) != "==" && tok->strAt(1) != "!=") { + comparisonOfBoolWithInvalidComparator(right, tok->str()); } } else if (tok->isNumber() && right->isBoolean()) { // number constant with boolean constant comparisonOfBoolWithIntError(tok, right->str(), false); @@ -1377,6 +1381,15 @@ void CheckOther::comparisonOfBoolWithIntError(const Token *tok, const std::strin "and it is compared against a integer value."); } +void CheckOther::comparisonOfBoolWithInvalidComparator(const Token *tok, const std::string &expression) +{ + reportError(tok, Severity::warning, "comparisonOfBoolWithInvalidComparator", + "Comparison of a boolean value using relational (<, >, <= or >=) operator.\n" + "The expression \"" + expression + "\" is of type 'bool' " + "and result is of type 'bool'. Comparing 'bool' value using relational (<, >, <= or >=)" + " operator could cause unexpected results."); +} + //--------------------------------------------------------------------------- // Find consecutive return, break, continue, goto or throw statements. e.g.: // break; break; diff --git a/lib/checkother.h b/lib/checkother.h index 001ba0ae0..ecc015720 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -273,6 +273,7 @@ private: void incorrectStringBooleanError(const Token *tok, const std::string& string); void incrementBooleanError(const Token *tok); void comparisonOfBoolWithIntError(const Token *tok, const std::string &expression, bool n0o1); + void comparisonOfBoolWithInvalidComparator(const Token *tok, const std::string &expression); void duplicateIfError(const Token *tok1, const Token *tok2); void duplicateBranchError(const Token *tok1, const Token *tok2); void duplicateExpressionError(const Token *tok1, const Token *tok2, const std::string &op); diff --git a/test/testother.cpp b/test/testother.cpp index 41a64b870..fc251545d 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -3205,6 +3205,62 @@ private: ); 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(bool x ) {\n" + " if ( x > false )\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean value using relational (<, >, <= or >=) operator.\n", errout.str()); + + check("void f(bool x ) {\n" + " if ( false < x )\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean value using relational (<, >, <= or >=) operator.\n", errout.str()); + + check("void f(bool x ) {\n" + " if ( x < false )\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean value using relational (<, >, <= or >=) operator.\n", errout.str()); + + check("void f(bool x ) {\n" + " if ( false > x )\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean value using relational (<, >, <= or >=) operator.\n", errout.str()); + + check("void f(bool x ) {\n" + " if ( x >= false )\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean value using relational (<, >, <= or >=) operator.\n", errout.str()); + + check("void f(bool x ) {\n" + " if ( false >= x )\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean value using relational (<, >, <= or >=) operator.\n", errout.str()); + + check("void f(bool x ) {\n" + " if ( x <= false )\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean value using relational (<, >, <= or >=) operator.\n", errout.str()); + + check("void f(bool x ) {\n" + " if ( false >= x )\n" + " a++;\n" + "}\n" + ); + ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean value using relational (<, >, <= or >=) operator.\n", errout.str()); + check("typedef int (*func)(bool invert);\n" "void x(int, func f);\n" "void foo(int error) {\n"