| 3381 | } |
| 3382 | |
| 3383 | bool isConstVarExpression(const Token *tok, const std::function<bool(const Token*)>& skipPredicate) |
| 3384 | { |
| 3385 | if (!tok) |
| 3386 | return false; |
| 3387 | if (tok->str() == "?" && tok->astOperand2() && tok->astOperand2()->str() == ":") // ternary operator |
| 3388 | return isConstVarExpression(tok->astOperand2()->astOperand1()) || isConstVarExpression(tok->astOperand2()->astOperand2()); // left and right of ":" |
| 3389 | if (skipPredicate && skipPredicate(tok)) |
| 3390 | return false; |
| 3391 | if (Token::simpleMatch(tok->previous(), "sizeof (")) |
| 3392 | return true; |
| 3393 | if (Token::Match(tok->previous(), "%name% (")) { |
| 3394 | if (Token::simpleMatch(tok->astOperand1(), ".") && !isConstVarExpression(tok->astOperand1(), skipPredicate)) |
| 3395 | return false; |
| 3396 | std::vector<const Token *> args = getArguments(tok); |
| 3397 | if (args.empty() && tok->previous()->function() && tok->previous()->function()->isConstexpr()) |
| 3398 | return true; |
| 3399 | return !args.empty() && std::all_of(args.cbegin(), args.cend(), [&](const Token* t) { |
| 3400 | return isConstVarExpression(t, skipPredicate); |
| 3401 | }); |
| 3402 | } |
| 3403 | if (isCPPCast(tok)) { |
| 3404 | return isConstVarExpression(tok->astOperand2(), skipPredicate); |
| 3405 | } |
| 3406 | if (Token::Match(tok, "( %type%")) |
| 3407 | return isConstVarExpression(tok->astOperand1(), skipPredicate); |
| 3408 | if (tok->str() == "::" && tok->hasKnownValue()) |
| 3409 | return isConstVarExpression(tok->astOperand2(), skipPredicate); |
| 3410 | if (Token::Match(tok, "%cop%|[|.")) { |
| 3411 | if (tok->astOperand1() && !isConstVarExpression(tok->astOperand1(), skipPredicate)) |
| 3412 | return false; |
| 3413 | if (tok->astOperand2() && !isConstVarExpression(tok->astOperand2(), skipPredicate)) |
| 3414 | return false; |
| 3415 | return true; |
| 3416 | } |
| 3417 | if (Token::Match(tok, "%bool%|%num%|%str%|%char%|nullptr|NULL")) |
| 3418 | return true; |
| 3419 | if (tok->isEnumerator()) |
| 3420 | return true; |
| 3421 | if (tok->variable()) |
| 3422 | return tok->variable()->isConst() && tok->variable()->nameToken() && tok->variable()->nameToken()->hasKnownValue(); |
| 3423 | return false; |
| 3424 | } |
| 3425 | |
| 3426 | static ExprUsage getFunctionUsage(const Token* tok, int indirect, const Settings& settings) |
| 3427 | { |
no test coverage detected