@@ -72,6 +72,13 @@ void CheckBool::incrementBooleanError(const Token *tok)
7272 );
7373}
7474
75+ static bool isConvertedToBool (const Token* tok)
76+ {
77+ if (!tok->astParent ())
78+ return false ;
79+ return astIsBool (tok->astParent ()) || Token::Match (tok->astParent ()->previous (), " if|while (" );
80+ }
81+
7582// ---------------------------------------------------------------------------
7683// if (bool & bool) -> if (bool && bool)
7784// if (bool | bool) -> if (bool || bool)
@@ -90,20 +97,29 @@ void CheckBool::checkBitwiseOnBoolean()
9097 for (const Scope * scope : symbolDatabase->functionScopes ) {
9198 for (const Token* tok = scope->bodyStart ->next (); tok != scope->bodyEnd ; tok = tok->next ()) {
9299 if (tok->isBinaryOp () && (tok->str () == " &" || tok->str () == " |" )) {
93- if (astIsBool (tok->astOperand1 ()) || astIsBool (tok->astOperand2 ())) {
94- if (tok->astOperand2 ()->variable () && tok->astOperand2 ()->variable ()->nameToken () == tok->astOperand2 ())
95- continue ;
96- const std::string expression = astIsBool (tok->astOperand1 ()) ? tok->astOperand1 ()->expressionString () : tok->astOperand2 ()->expressionString ();
97- bitwiseOnBooleanError (tok, expression, tok->str () == " &" ? " &&" : " ||" );
98- }
100+ if (!(astIsBool (tok->astOperand1 ()) || astIsBool (tok->astOperand2 ())))
101+ continue ;
102+ if (tok->str () == " |" && !isConvertedToBool (tok) && !(astIsBool (tok->astOperand1 ()) && astIsBool (tok->astOperand2 ())))
103+ continue ;
104+ if (!isConstExpression (tok->astOperand1 (), mSettings ->library , true , mTokenizer ->isCPP ()))
105+ continue ;
106+ if (!isConstExpression (tok->astOperand2 (), mSettings ->library , true , mTokenizer ->isCPP ()))
107+ continue ;
108+ if (tok->astOperand2 ()->variable () && tok->astOperand2 ()->variable ()->nameToken () == tok->astOperand2 ())
109+ continue ;
110+ const std::string expression = astIsBool (tok->astOperand1 ()) ? tok->astOperand1 ()->expressionString ()
111+ : tok->astOperand2 ()->expressionString ();
112+ bitwiseOnBooleanError (tok, expression, tok->str () == " &" ? " &&" : " ||" );
99113 }
100114 }
101115 }
102116}
103117
104- void CheckBool::bitwiseOnBooleanError (const Token * tok, const std::string & expression, const std::string & op)
118+ void CheckBool::bitwiseOnBooleanError (const Token* tok, const std::string& expression, const std::string& op)
105119{
106- reportError (tok, Severity::style, " bitwiseOnBoolean" ,
120+ reportError (tok,
121+ Severity::style,
122+ " bitwiseOnBoolean" ,
107123 " Boolean expression '" + expression + " ' is used in bitwise operation. Did you mean '" + op + " '?" ,
108124 CWE398,
109125 Certainty::inconclusive);
0 commit comments