| 3652 | } |
| 3653 | |
| 3654 | static void valueFlowSymbolicOperators(const SymbolDatabase& symboldatabase, const Settings& settings) |
| 3655 | { |
| 3656 | for (const Scope* scope : symboldatabase.functionScopes) { |
| 3657 | for (auto* tok = const_cast<Token*>(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) { |
| 3658 | if (tok->hasKnownIntValue()) |
| 3659 | continue; |
| 3660 | |
| 3661 | if (Token::Match(tok, "abs|labs|llabs|fabs|fabsf|fabsl (")) { |
| 3662 | const Token* arg = tok->next()->astOperand2(); |
| 3663 | if (!arg) |
| 3664 | continue; |
| 3665 | if (arg->exprId() == 0) |
| 3666 | continue; |
| 3667 | ValueFlow::Value c = inferCondition(">=", arg, 0); |
| 3668 | if (!c.isKnown()) |
| 3669 | continue; |
| 3670 | |
| 3671 | ValueFlow::Value v = makeSymbolic(arg); |
| 3672 | v.errorPath = std::move(c.errorPath); |
| 3673 | v.errorPath.emplace_back(tok, "Passed to " + tok->str()); |
| 3674 | if (c.intvalue == 0) |
| 3675 | v.setImpossible(); |
| 3676 | else |
| 3677 | v.setKnown(); |
| 3678 | setTokenValue(tok->next(), std::move(v), settings); |
| 3679 | } else if (Token::Match(tok, "*|/|<<|>>|^|+|-|%or%")) { |
| 3680 | if (!tok->astOperand1()) |
| 3681 | continue; |
| 3682 | if (!tok->astOperand2()) |
| 3683 | continue; |
| 3684 | if (!astIsIntegral(tok->astOperand1(), false) && !astIsIntegral(tok->astOperand2(), false)) |
| 3685 | continue; |
| 3686 | const ValueFlow::Value* constant = nullptr; |
| 3687 | const Token* vartok = nullptr; |
| 3688 | if (const ValueFlow::Value* v = tok->astOperand1()->getKnownValue(ValueFlow::Value::ValueType::INT)) { |
| 3689 | constant = v; |
| 3690 | vartok = tok->astOperand2(); |
| 3691 | } |
| 3692 | if (const ValueFlow::Value* v = tok->astOperand2()->getKnownValue(ValueFlow::Value::ValueType::INT)) { |
| 3693 | constant = v; |
| 3694 | vartok = tok->astOperand1(); |
| 3695 | } |
| 3696 | if (!constant) |
| 3697 | continue; |
| 3698 | if (!vartok) |
| 3699 | continue; |
| 3700 | if (vartok->exprId() == 0) |
| 3701 | continue; |
| 3702 | if (Token::Match(tok, "<<|>>|/|-") && !astIsLHS(vartok)) |
| 3703 | continue; |
| 3704 | if (Token::Match(tok, "<<|>>|^|+|-|%or%") && constant->intvalue != 0) |
| 3705 | continue; |
| 3706 | if (Token::Match(tok, "*|/") && constant->intvalue != 1) |
| 3707 | continue; |
| 3708 | std::vector<ValueFlow::Value> values = {makeSymbolic(vartok)}; |
| 3709 | std::unordered_set<nonneg int> ids = {vartok->exprId()}; |
| 3710 | std::copy_if(vartok->values().cbegin(), |
| 3711 | vartok->values().cend(), |
no test coverage detected