--------------------------------------------------------------------------- if (bool & bool) -> if (bool && bool) if (bool | bool) -> if (bool || bool) ---------------------------------------------------------------------------
| 84 | // if (bool | bool) -> if (bool || bool) |
| 85 | //--------------------------------------------------------------------------- |
| 86 | void CheckBoolImpl::checkBitwiseOnBoolean() |
| 87 | { |
| 88 | if (!mSettings.isPremiumEnabled("bitwiseOnBoolean") && |
| 89 | !mSettings.severity.isEnabled(Severity::style) && |
| 90 | // danmar: this is inconclusive because I don't like that there are |
| 91 | // warnings for calculations. Example: set_flag(a & b); |
| 92 | !mSettings.certainty.isEnabled(Certainty::inconclusive)) |
| 93 | return; |
| 94 | |
| 95 | logChecker("CheckBool::checkBitwiseOnBoolean"); // style,inconclusive |
| 96 | |
| 97 | const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); |
| 98 | for (const Scope * scope : symbolDatabase->functionScopes) { |
| 99 | for (const Token* tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) { |
| 100 | if (tok->isBinaryOp()) { |
| 101 | bool isCompound{}; |
| 102 | if (tok->str() == "&" || tok->str() == "|") |
| 103 | isCompound = false; |
| 104 | else if (tok->str() == "&=" || tok->str() == "|=") |
| 105 | isCompound = true; |
| 106 | else |
| 107 | continue; |
| 108 | const bool isBoolOp1 = astIsBool(tok->astOperand1()); |
| 109 | const bool isBoolOp2 = astIsBool(tok->astOperand2()); |
| 110 | if (!tok->astOperand1()->valueType() || !tok->astOperand2()->valueType()) |
| 111 | continue; |
| 112 | if (!(isBoolOp1 || isBoolOp2)) |
| 113 | continue; |
| 114 | if (isCompound && (!isBoolOp1 || isBoolOp2)) |
| 115 | continue; |
| 116 | if (tok->str() == "|" && !isConvertedToBool(tok) && !(isBoolOp1 && isBoolOp2)) |
| 117 | continue; |
| 118 | // first operand will always be evaluated |
| 119 | if (!isConstExpression(tok->astOperand2(), mSettings.library)) |
| 120 | continue; |
| 121 | if (tok->astOperand2()->variable() && tok->astOperand2()->variable()->nameToken() == tok->astOperand2()) |
| 122 | continue; |
| 123 | const std::string expression = (isBoolOp1 ? tok->astOperand1() : tok->astOperand2())->expressionString(); |
| 124 | bitwiseOnBooleanError(tok, expression, tok->str() == "&" ? "&&" : "||", isCompound); |
| 125 | } |
| 126 | } |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | void CheckBoolImpl::bitwiseOnBooleanError(const Token* tok, const std::string& expression, const std::string& op, bool isCompound) |
| 131 | { |
no test coverage detected