| 3384 | |
| 3385 | // |
| 3386 | static void valueFlowConditionExpressions(const TokenList& tokenlist, |
| 3387 | const SymbolDatabase& symboldatabase, |
| 3388 | ErrorLogger& errorLogger, |
| 3389 | const Settings& settings) |
| 3390 | { |
| 3391 | if (!settings.daca && !settings.vfOptions.doConditionExpressionAnalysis) { |
| 3392 | if (settings.debugwarnings) { |
| 3393 | ErrorMessage::FileLocation loc(tokenlist.getSourceFilePath(), 0, 0); |
| 3394 | const ErrorMessage errmsg( |
| 3395 | {std::move(loc)}, |
| 3396 | tokenlist.getSourceFilePath(), |
| 3397 | Severity::debug, |
| 3398 | "Analysis of condition expressions is disabled. Use --check-level=exhaustive to enable it.", |
| 3399 | "normalCheckLevelConditionExpressions", |
| 3400 | Certainty::normal); |
| 3401 | errorLogger.reportErr(errmsg); |
| 3402 | } |
| 3403 | return; |
| 3404 | } |
| 3405 | |
| 3406 | for (const Scope* scope : symboldatabase.functionScopes) { |
| 3407 | if (const Token* incompleteTok = findIncompleteVar(scope->bodyStart, scope->bodyEnd)) { |
| 3408 | if (settings.debugwarnings) |
| 3409 | bailoutIncompleteVar(tokenlist, |
| 3410 | errorLogger, |
| 3411 | incompleteTok, |
| 3412 | "Skipping function due to incomplete variable " + incompleteTok->str()); |
| 3413 | continue; |
| 3414 | } |
| 3415 | |
| 3416 | if (settings.daca && !settings.vfOptions.doConditionExpressionAnalysis) |
| 3417 | continue; |
| 3418 | |
| 3419 | for (auto* tok = const_cast<Token*>(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) { |
| 3420 | if (!Token::simpleMatch(tok, "if (")) |
| 3421 | continue; |
| 3422 | Token* parenTok = tok->next(); |
| 3423 | if (!Token::simpleMatch(parenTok->link(), ") {")) |
| 3424 | continue; |
| 3425 | const Token* condTok = parenTok->astOperand2(); |
| 3426 | if (condTok->exprId() == 0) |
| 3427 | continue; |
| 3428 | if (condTok->hasKnownIntValue()) |
| 3429 | continue; |
| 3430 | if (!isConstExpression(condTok, settings.library)) |
| 3431 | continue; |
| 3432 | const bool isOp = condTok->isComparisonOp() || condTok->tokType() == Token::eLogicalOp; |
| 3433 | const bool is1 = isOp || astIsBool(condTok); |
| 3434 | |
| 3435 | Token* blockTok = parenTok->link()->tokAt(1); |
| 3436 | Token* startTok = blockTok; |
| 3437 | // Inner condition |
| 3438 | { |
| 3439 | for (const Token* condTok2 : getConditions(condTok, "&&")) { |
| 3440 | if (is1) { |
| 3441 | const bool isBool = astIsBool(condTok2) || Token::Match(condTok2, "%comp%|%oror%|&&"); |
| 3442 | auto a1 = makeSameExpressionAnalyzer( |
| 3443 | condTok2, |
no test coverage detected