----------------------------------------------------------------------------- -----------------------------------------------------------------------------
| 334 | //----------------------------------------------------------------------------- |
| 335 | //----------------------------------------------------------------------------- |
| 336 | void CheckBoolImpl::checkComparisonOfBoolExpressionWithInt() |
| 337 | { |
| 338 | if (!mSettings.severity.isEnabled(Severity::warning) && !mSettings.isPremiumEnabled("compareBoolExpressionWithInt")) |
| 339 | return; |
| 340 | |
| 341 | logChecker("CheckBool::checkComparisonOfBoolExpressionWithInt"); // warning |
| 342 | |
| 343 | const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase(); |
| 344 | |
| 345 | for (const Scope * scope : symbolDatabase->functionScopes) { |
| 346 | for (const Token* tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) { |
| 347 | if (!tok->isComparisonOp()) |
| 348 | continue; |
| 349 | |
| 350 | const Token* numTok = nullptr; |
| 351 | const Token* boolExpr = nullptr; |
| 352 | bool numInRhs; |
| 353 | if (astIsBool(tok->astOperand1())) { |
| 354 | boolExpr = tok->astOperand1(); |
| 355 | numTok = tok->astOperand2(); |
| 356 | numInRhs = true; |
| 357 | } else if (astIsBool(tok->astOperand2())) { |
| 358 | boolExpr = tok->astOperand2(); |
| 359 | numTok = tok->astOperand1(); |
| 360 | numInRhs = false; |
| 361 | } else { |
| 362 | continue; |
| 363 | } |
| 364 | |
| 365 | if (!numTok || !boolExpr) |
| 366 | continue; |
| 367 | |
| 368 | if (boolExpr->isOp() && numTok->isName() && Token::Match(tok, "==|!=")) |
| 369 | // there is weird code such as: ((a<b)==c) |
| 370 | // but it is probably written this way by design. |
| 371 | continue; |
| 372 | |
| 373 | if (astIsBool(numTok)) |
| 374 | continue; |
| 375 | |
| 376 | const ValueFlow::Value *minval = numTok->getValueLE(0, mSettings); |
| 377 | if (minval && minval->intvalue == 0 && |
| 378 | (numInRhs ? Token::Match(tok, ">|==|!=") |
| 379 | : Token::Match(tok, "<|==|!="))) |
| 380 | minval = nullptr; |
| 381 | |
| 382 | const ValueFlow::Value *maxval = numTok->getValueGE(1, mSettings); |
| 383 | if (maxval && maxval->intvalue == 1 && |
| 384 | (numInRhs ? Token::Match(tok, "<|==|!=") |
| 385 | : Token::Match(tok, ">|==|!="))) |
| 386 | maxval = nullptr; |
| 387 | |
| 388 | if (minval || maxval) { |
| 389 | const bool not0or1 = (minval && minval->intvalue < 0) || (maxval && maxval->intvalue > 1); |
| 390 | comparisonOfBoolExpressionWithIntError(tok, not0or1); |
| 391 | } |
| 392 | } |
| 393 | } |
no test coverage detected