Improve check: Clarify condition (using boolean result in bitwise operation)

This commit is contained in:
Daniel Marjamäki 2011-08-19 13:40:54 +02:00
parent 0d7c80ef21
commit 40b493e621
3 changed files with 46 additions and 4 deletions

View File

@ -142,6 +142,7 @@ void CheckOther::clarifyCondition()
{
if (!_settings->isEnabled("style"))
return;
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
{
if (Token::Match(tok, "( %var% [=&|^]"))
@ -154,19 +155,45 @@ void CheckOther::clarifyCondition()
break;
else if (Token::Match(tok2, "<|<=|==|!=|>|>="))
{
clarifyConditionError(tok, tok->strAt(2) == "=");
clarifyConditionError(tok, tok->strAt(2) == "=", false);
break;
}
}
}
}
// using boolean result in bitwise operation ! x [&|^]
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
{
if (Token::Match(tok, "!|<|<=|==|!=|>|>="))
{
const Token *tok2 = tok->next();
while (tok2 && (tok2->isName() || Token::Match(tok2,".|(|[")))
{
if (Token::Match(tok2, "(|["))
tok2 = tok2->link();
tok2 = tok2->next();
}
if (Token::Match(tok2, "[&|^]"))
{
clarifyConditionError(tok,false,true);
}
}
}
}
void CheckOther::clarifyConditionError(const Token *tok, bool assign)
void CheckOther::clarifyConditionError(const Token *tok, bool assign, bool boolop)
{
std::string errmsg;
if (assign)
errmsg = "Suspicious condition (assignment+comparison), it can be clarified with parentheses";
else if (boolop)
errmsg = "Boolean result is used in bitwise operation. Clarify expression with parentheses\n"
"Suspicious expression. Boolean result is used in bitwise operation. The ! operator "
"and the comparison operators have higher precedence than bitwise operators. "
"It is recommended that the expression is clarified with parentheses.";
else
errmsg = "Suspicious condition (bitwise operator + comparison), it can be clarified with parentheses\n"
"Suspicious condition. Comparison operators have higher precedence than bitwise operators. Please clarify the condition with parentheses.";

View File

@ -112,7 +112,7 @@ public:
/** @brief Suspicious condition (assignment+comparison) */
void clarifyCondition();
void clarifyConditionError(const Token *tok, bool assign);
void clarifyConditionError(const Token *tok, bool assign, bool boolop);
/** @brief Are there C-style pointer casts in a c++ file? */
void warningOldStylePointerCast();
@ -319,7 +319,7 @@ public:
c.catchExceptionByValueError(0);
c.memsetZeroBytesError(0, "varname");
c.clarifyCalculationError(0, "+");
c.clarifyConditionError(0, true);
c.clarifyConditionError(0, true, false);
c.incorrectStringCompareError(0, "substr", "\"Hello World\"", "12");
c.incrementBooleanError(0);
c.comparisonOfBoolWithIntError(0, "varname");

View File

@ -116,6 +116,7 @@ private:
TEST_CASE(clarifyCondition1); // if (a = b() < 0)
TEST_CASE(clarifyCondition2); // if (a & b == c)
TEST_CASE(clarifyCondition3); // if (! a & b)
TEST_CASE(incorrectStringCompare);
@ -2652,6 +2653,20 @@ private:
ASSERT_EQUALS("[test.cpp:2]: (style) Suspicious condition (bitwise operator + comparison), it can be clarified with parentheses\n", errout.str());
}
// clarify condition that uses ! operator and then bitwise operator
void clarifyCondition3()
{
check("void f(int w) {\n"
" if(!w & 0x8000) {}\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Boolean result is used in bitwise operation. Clarify expression with parentheses\n", errout.str());
check("void f() {\n"
" if (x == foo() & 2) {}\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (style) Boolean result is used in bitwise operation. Clarify expression with parentheses\n", errout.str());
}
void incorrectStringCompare()
{
check("int f() {\n"