From b09bcdc38cca80b2c52af1eff6cd50bc95f3b63c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 27 Jun 2020 08:13:22 +0200 Subject: [PATCH] Use ValueFlow for compareBoolExpressionWithInt --- lib/checkbool.cpp | 33 ++++++++++++++++++--------------- lib/checkbool.h | 2 +- test/testbool.cpp | 47 +++++++++++++++-------------------------------- 3 files changed, 34 insertions(+), 48 deletions(-) diff --git a/lib/checkbool.cpp b/lib/checkbool.cpp index 4e418a470..1f1a52c49 100644 --- a/lib/checkbool.cpp +++ b/lib/checkbool.cpp @@ -333,26 +333,29 @@ void CheckBool::checkComparisonOfBoolExpressionWithInt() if (astIsBool(numTok)) continue; - if (numTok->isNumber()) { - const MathLib::bigint num = MathLib::toLongNumber(numTok->str()); - if (num==0 && - (numInRhs ? Token::Match(tok, ">|==|!=") - : Token::Match(tok, "<|==|!="))) - continue; - if (num==1 && - (numInRhs ? Token::Match(tok, "<|==|!=") - : Token::Match(tok, ">|==|!="))) - continue; - comparisonOfBoolExpressionWithIntError(tok, true); - } else if (astIsIntegral(numTok, false) && mTokenizer->isCPP()) - comparisonOfBoolExpressionWithIntError(tok, false); + const ValueFlow::Value *minval = numTok->getValueLE(0, mSettings); + if (minval && minval->intvalue == 0 && + (numInRhs ? Token::Match(tok, ">|==|!=") + : Token::Match(tok, "<|==|!="))) + minval = nullptr; + + const ValueFlow::Value *maxval = numTok->getValueGE(1, mSettings); + if (maxval && maxval->intvalue == 1 && + (numInRhs ? Token::Match(tok, "<|==|!=") + : Token::Match(tok, ">|==|!="))) + maxval = nullptr; + + if (minval || maxval) { + bool not0or1 = (minval && minval->intvalue < 0) || (maxval && maxval->intvalue > 1); + comparisonOfBoolExpressionWithIntError(tok, not0or1); + } } } } -void CheckBool::comparisonOfBoolExpressionWithIntError(const Token *tok, bool n0o1) +void CheckBool::comparisonOfBoolExpressionWithIntError(const Token *tok, bool not0or1) { - if (n0o1) + if (not0or1) reportError(tok, Severity::warning, "compareBoolExpressionWithInt", "Comparison of a boolean expression with an integer other than 0 or 1.", CWE398, false); else diff --git a/lib/checkbool.h b/lib/checkbool.h index 335fe027e..4b2cd0689 100644 --- a/lib/checkbool.h +++ b/lib/checkbool.h @@ -107,7 +107,7 @@ private: void assignBoolToPointerError(const Token *tok); void assignBoolToFloatError(const Token *tok); void bitwiseOnBooleanError(const Token *tok, const std::string &expression, const std::string &op); - void comparisonOfBoolExpressionWithIntError(const Token *tok, bool n0o1); + void comparisonOfBoolExpressionWithIntError(const Token *tok, bool not0or1); void pointerArithBoolError(const Token *tok); void returnValueBoolError(const Token *tok); diff --git a/test/testbool.cpp b/test/testbool.cpp index 05e18942f..4e12d4919 100644 --- a/test/testbool.cpp +++ b/test/testbool.cpp @@ -308,7 +308,7 @@ private: " 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()); + ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean expression with an integer.\n", errout.str()); check("void f(int x) {\n" " if ((5 && x) < 1)\n" @@ -322,7 +322,7 @@ private: " 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()); + ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean expression with an integer.\n", errout.str()); check("void f(int x) {\n" @@ -337,7 +337,7 @@ private: " 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()); + ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean expression with an integer.\n", errout.str()); check("void f(int x) {\n" " if (1 > (5 && x))\n" @@ -351,7 +351,7 @@ private: " 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()); + ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean expression with an integer.\n", errout.str()); check("void f(bool x ) {\n" " if ( x > false )\n" @@ -422,16 +422,6 @@ private: check("int f() { return (!a+b b) < c;\n" "}"); - ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean expression with an integer.\n", errout.str()); + ASSERT_EQUALS("", errout.str()); check("void f(int a, int b, int c) {\n" " return x(a > b) < c;\n" @@ -629,14 +619,8 @@ private: " printf(\"foo\");\n" " }\n" "}\n" - "bool compare(int temp){\n" - " if(temp==4){\n" - " return true;\n" - " }\n" - " else\n" - " return false;\n" - "}"); - ASSERT_EQUALS("[test.cpp:3]: (warning) Comparison of a boolean expression with an integer.\n" + "bool compare(int temp);"); + ASSERT_EQUALS("[test.cpp:3]: (warning) Comparison of a boolean expression with an integer other than 0 or 1.\n" "[test.cpp:3]: (style) Comparison of a function returning boolean value using relational (<, >, <= or >=) operator.\n", errout.str()); } @@ -950,14 +934,14 @@ private: " printf(\"foo\");\n" " }\n" "}"); - ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean expression with an integer.\n", errout.str()); + ASSERT_EQUALS("", errout.str()); check("void f(int x, bool y) {\n" " if (x == y) {\n" " printf(\"foo\");\n" " }\n" "}"); - ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean expression with an integer.\n", errout.str()); + ASSERT_EQUALS("", errout.str()); check("void f(bool x, bool y) {\n" " if (x == y) {\n" @@ -980,15 +964,14 @@ private: " printf(\"foo\");\n" " }\n" "}"); - ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean expression with an integer.\n" - "[test.cpp:2]: (warning) Comparison of a boolean value using relational operator (<, >, <= or >=).\n", errout.str()); + ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean value using relational operator (<, >, <= or >=).\n", errout.str()); check("void f(int y) {\n" " if (true == y) {\n" " printf(\"foo\");\n" " }\n" "}"); - ASSERT_EQUALS("[test.cpp:2]: (warning) Comparison of a boolean expression with an integer.\n", errout.str()); + ASSERT_EQUALS("", errout.str()); check("void f(bool y) {\n" " if (y == true) {\n" @@ -1049,7 +1032,7 @@ private: " if (expectedResult == res)\n" " throw 2;\n" "}"); - ASSERT_EQUALS("[test.cpp:4]: (warning) Comparison of a boolean expression with an integer.\n", errout.str()); + ASSERT_EQUALS("", errout.str()); check("bool Fun();\n" "void Test(bool expectedResult) {\n" @@ -1057,7 +1040,7 @@ private: " if (5 + expectedResult == res)\n" " throw 2;\n" "}"); - ASSERT_EQUALS("[test.cpp:4]: (warning) Comparison of a boolean expression with an integer.\n", errout.str()); + ASSERT_EQUALS("", errout.str()); check("int Fun();\n" "void Test(bool expectedResult) {\n" @@ -1073,7 +1056,7 @@ private: " if (expectedResult == res + 5)\n" " throw 2;\n" "}"); - ASSERT_EQUALS("[test.cpp:4]: (warning) Comparison of a boolean expression with an integer.\n", errout.str()); + TODO_ASSERT_EQUALS("error", "", errout.str()); } void comparisonOfBoolWithInt9() { // #9304