| 309 | } |
| 310 | |
| 311 | void CheckConditionImpl::checkBadBitmaskCheck() |
| 312 | { |
| 313 | if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("badBitmaskCheck")) |
| 314 | return; |
| 315 | |
| 316 | logChecker("CheckCondition::checkBadBitmaskCheck"); // style |
| 317 | |
| 318 | for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { |
| 319 | if (tok->str() == "|" && tok->astOperand1() && tok->astOperand2() && tok->astParent()) { |
| 320 | const Token* parent = tok->astParent(); |
| 321 | const bool isBoolean = Token::Match(parent, "&&|%oror%") || |
| 322 | (parent->str() == "?" && parent->astOperand1() == tok) || |
| 323 | (parent->str() == "=" && parent->astOperand2() == tok && parent->astOperand1() && parent->astOperand1()->variable() && Token::Match(parent->astOperand1()->variable()->typeStartToken(), "bool|_Bool")) || |
| 324 | (parent->str() == "(" && Token::Match(parent->astOperand1(), "if|while")) || |
| 325 | (parent->str() == "return" && parent->astOperand1() == tok && inBooleanFunction(tok)); |
| 326 | |
| 327 | const bool isTrue = (tok->astOperand1()->hasKnownIntValue() && tok->astOperand1()->getKnownIntValue() != 0) || |
| 328 | (tok->astOperand2()->hasKnownIntValue() && tok->astOperand2()->getKnownIntValue() != 0); |
| 329 | |
| 330 | if (isBoolean && isTrue) |
| 331 | badBitmaskCheckError(tok); |
| 332 | |
| 333 | // If there are #ifdef in the expression don't warn about redundant | to avoid FP |
| 334 | const auto& startStop = tok->findExpressionStartEndTokens(); |
| 335 | if (mTokenizer->hasIfdef(startStop.first, startStop.second)) |
| 336 | continue; |
| 337 | |
| 338 | const bool isZero1 = (tok->astOperand1()->hasKnownIntValue() && tok->astOperand1()->getKnownIntValue() == 0); |
| 339 | const bool isZero2 = (tok->astOperand2()->hasKnownIntValue() && tok->astOperand2()->getKnownIntValue() == 0); |
| 340 | if (!isZero1 && !isZero2) |
| 341 | continue; |
| 342 | |
| 343 | if (!tok->isExpandedMacro() && |
| 344 | !(isZero1 && isOperandExpanded(tok->astOperand1())) && |
| 345 | !(isZero2 && isOperandExpanded(tok->astOperand2()))) |
| 346 | badBitmaskCheckError(tok, /*isNoOp*/ true); |
| 347 | } |
| 348 | } |
| 349 | } |
| 350 | |
| 351 | void CheckConditionImpl::badBitmaskCheckError(const Token *tok, bool isNoOp) |
| 352 | { |
no test coverage detected