badBitmaskCheck: Avoid FP when there is #ifdef in expression

This commit is contained in:
Daniel Marjamäki 2022-07-28 21:56:05 +02:00
parent 13c80d6cce
commit 898ad314ab
2 changed files with 18 additions and 3 deletions

View File

@ -293,7 +293,7 @@ static bool inBooleanFunction(const Token *tok)
void CheckCondition::checkBadBitmaskCheck() void CheckCondition::checkBadBitmaskCheck()
{ {
if (!mSettings->severity.isEnabled(Severity::warning)) if (!mSettings->severity.isEnabled(Severity::style))
return; return;
for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
@ -311,6 +311,11 @@ void CheckCondition::checkBadBitmaskCheck()
if (isBoolean && isTrue) if (isBoolean && isTrue)
badBitmaskCheckError(tok); badBitmaskCheckError(tok);
// If there are #ifdef in the expression don't warn about redundant | to avoid FP
const auto& startStop = tok->findExpressionStartEndTokens();
if (mTokenizer->hasIfdef(startStop.first, startStop.second))
continue;
const bool isZero1 = (tok->astOperand1()->hasKnownIntValue() && tok->astOperand1()->values().front().intvalue == 0); const bool isZero1 = (tok->astOperand1()->hasKnownIntValue() && tok->astOperand1()->values().front().intvalue == 0);
const bool isZero2 = (tok->astOperand2()->hasKnownIntValue() && tok->astOperand2()->values().front().intvalue == 0); const bool isZero2 = (tok->astOperand2()->hasKnownIntValue() && tok->astOperand2()->values().front().intvalue == 0);
@ -323,7 +328,7 @@ void CheckCondition::checkBadBitmaskCheck()
void CheckCondition::badBitmaskCheckError(const Token *tok, bool isNoOp) void CheckCondition::badBitmaskCheckError(const Token *tok, bool isNoOp)
{ {
if (isNoOp) if (isNoOp)
reportError(tok, Severity::warning, "badBitmaskCheck", "Operator '|' with one operand equal to zero is redundant.", CWE571, Certainty::normal); reportError(tok, Severity::style, "badBitmaskCheck", "Operator '|' with one operand equal to zero is redundant.", CWE571, Certainty::normal);
else else
reportError(tok, Severity::warning, "badBitmaskCheck", "Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'?", CWE571, Certainty::normal); reportError(tok, Severity::warning, "badBitmaskCheck", "Result of operator '|' is always true if one operand is non-zero. Did you intend to use '&'?", CWE571, Certainty::normal);
} }

View File

@ -903,7 +903,7 @@ private:
" int j = 0;\n" " int j = 0;\n"
" if (i | j) {}\n" " if (i | j) {}\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:3]: (warning) Operator '|' with one operand equal to zero is redundant.\n", errout.str()); ASSERT_EQUALS("[test.cpp:3]: (style) Operator '|' with one operand equal to zero is redundant.\n", errout.str());
check("#define EIGHTTOIS(x) (((x) << 8) | (x))\n" check("#define EIGHTTOIS(x) (((x) << 8) | (x))\n"
"int f() {\n" "int f() {\n"
@ -916,6 +916,16 @@ private:
" *pFd = open(s, O_RDONLY | O_BINARY, 0);\n" " *pFd = open(s, O_RDONLY | O_BINARY, 0);\n"
"}\n"); "}\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("const int FEATURE_BITS = x |\n"
"#if FOO_ENABLED\n"
" FEATURE_FOO |\n"
"#endif\n"
"#if BAR_ENABLED\n"
" FEATURE_BAR |\n"
"#endif\n"
" 0;");
ASSERT_EQUALS("", errout.str());
} }