Fixed #2955 (New check: Using && instead of &)

This commit is contained in:
Zachary Blair 2011-10-10 10:11:17 -07:00
parent 742858b67c
commit fcf360825a
3 changed files with 181 additions and 0 deletions

View File

@ -2573,6 +2573,41 @@ void CheckOther::assignBoolToPointerError(const Token *tok)
"Assigning bool value to pointer (converting bool value to address)"); "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. // Check testing sign of unsigned variables.
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@ -71,6 +71,7 @@ public:
checkOther.checkVariableScope(); checkOther.checkVariableScope();
checkOther.clarifyCondition(); // not simplified because ifAssign checkOther.clarifyCondition(); // not simplified because ifAssign
checkOther.checkComparisonOfBoolExpressionWithInt();
} }
/** @brief Run checks against the simplified token list */ /** @brief Run checks against the simplified token list */
@ -229,6 +230,9 @@ public:
/** @brief %Check for using bool in bitwise expression */ /** @brief %Check for using bool in bitwise expression */
void checkBitwiseOnBoolean(); void checkBitwiseOnBoolean();
/** @brief %Check for comparing a bool expression with an integer other than 0 or 1 */
void checkComparisonOfBoolExpressionWithInt();
// Error messages.. // Error messages..
void cstyleCastError(const Token *tok); void cstyleCastError(const Token *tok);
void dangerousUsageStrtolError(const Token *tok); void dangerousUsageStrtolError(const Token *tok);
@ -266,6 +270,7 @@ public:
void unsignedLessThanZeroError(const Token *tok, const std::string &varname); void unsignedLessThanZeroError(const Token *tok, const std::string &varname);
void unsignedPositiveError(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 bitwiseOnBooleanError(const Token *tok, const std::string &varname, const std::string &op);
void comparisonOfBoolExpressionWithIntError(const Token *tok);
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings)
{ {
@ -315,6 +320,7 @@ public:
c.unsignedLessThanZeroError(0, "varname"); c.unsignedLessThanZeroError(0, "varname");
c.unsignedPositiveError(0, "varname"); c.unsignedPositiveError(0, "varname");
c.bitwiseOnBooleanError(0, "varname", "&&"); c.bitwiseOnBooleanError(0, "varname", "&&");
c.comparisonOfBoolExpressionWithIntError(0);
} }
std::string myName() const std::string myName() const
@ -358,6 +364,7 @@ public:
"* Clarify calculation with parentheses\n" "* Clarify calculation with parentheses\n"
"* using increment on boolean\n" "* using increment on boolean\n"
"* comparison of a boolean with a non-zero integer\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 (assignment+comparison)\n"
"* suspicious condition (runtime comparison of string literals)\n" "* suspicious condition (runtime comparison of string literals)\n"
"* duplicate break statement\n" "* duplicate break statement\n"

View File

@ -123,6 +123,8 @@ private:
TEST_CASE(clarifyCondition4); // ticket #3110 TEST_CASE(clarifyCondition4); // ticket #3110
TEST_CASE(bitwiseOnBoolean); // if (bool & bool) TEST_CASE(bitwiseOnBoolean); // if (bool & bool)
TEST_CASE(comparisonOfBoolExpressionWithInt);
TEST_CASE(incorrectStringCompare); TEST_CASE(incorrectStringCompare);
TEST_CASE(incrementBoolean); TEST_CASE(incrementBoolean);
@ -167,6 +169,7 @@ private:
checkOther.checkDuplicateBranch(); checkOther.checkDuplicateBranch();
checkOther.checkDuplicateExpression(); checkOther.checkDuplicateExpression();
checkOther.checkBitwiseOnBoolean(); checkOther.checkBitwiseOnBoolean();
checkOther.checkComparisonOfBoolExpressionWithInt();
// Simplify token list.. // Simplify token list..
tokenizer.simplifyTokenList(); tokenizer.simplifyTokenList();
@ -2464,6 +2467,142 @@ private:
ASSERT_EQUALS("", errout.str()); 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() void catchExceptionByValue()
{ {
check("void f() {\n" check("void f() {\n"