@@ -632,10 +632,6 @@ static MathLib::bigint asInt(const ValueFlow::Value& value)
632632 return value.isFloatValue () ? static_cast <MathLib::bigint>(value.floatValue ) : value.intvalue ;
633633}
634634
635- static std::string removeAssign (const std::string& assign) {
636- return std::string{assign.cbegin (), assign.cend () - 1 };
637- }
638-
639635namespace {
640636 struct assign {
641637 template <class T , class U >
@@ -651,22 +647,23 @@ static bool isIntegralValue(const ValueFlow::Value& value)
651647 return value.isIntValue () || value.isIteratorValue () || value.isSymbolicValue ();
652648}
653649
654- static ValueFlow::Value evaluate (const std::string& op, const ValueFlow::Value& lhs, const ValueFlow::Value& rhs)
650+ static ValueFlow::Value evaluate (const Token* op, const ValueFlow::Value& lhs, const ValueFlow::Value& rhs, bool removeAssign = false )
655651{
652+ const std::string opStr = removeAssign ? op->str ().substr (0 , op->str ().size () - 1 ) : op->str ();
656653 ValueFlow::Value result;
657654 if (lhs.isImpossible () && rhs.isImpossible ())
658655 return ValueFlow::Value::unknown ();
659656 if (lhs.isImpossible () || rhs.isImpossible ()) {
660657 // noninvertible
661- if (contains ({" %" , " /" , " &" , " |" }, op ))
658+ if (contains ({" %" , " /" , " &" , " |" }, opStr ))
662659 return ValueFlow::Value::unknown ();
663660 result.setImpossible ();
664661 }
665662 if (isNumericValue (lhs) && isNumericValue (rhs)) {
666663 if (lhs.isFloatValue () || rhs.isFloatValue ()) {
667- result.valueType = ValueFlow::Value::ValueType::FLOAT;
664+ result.valueType = op-> isArithmeticalOp () ? ValueFlow::Value::ValueType::FLOAT : ValueFlow::Value::ValueType::INT ;
668665 bool error = false ;
669- result.floatValue = calculate (op , asFloat (lhs), asFloat (rhs), &error);
666+ result.floatValue = calculate (opStr , asFloat (lhs), asFloat (rhs), &error);
670667 if (error)
671668 return ValueFlow::Value::unknown ();
672669 return result;
@@ -678,12 +675,12 @@ static ValueFlow::Value evaluate(const std::string& op, const ValueFlow::Value&
678675 // If not the same type then one must be int
679676 if (lhs.valueType != rhs.valueType && !lhs.isIntValue () && !rhs.isIntValue ())
680677 return ValueFlow::Value::unknown ();
681- const bool compareOp = contains ({" ==" , " !=" , " <" , " >" , " >=" , " <=" }, op );
678+ const bool compareOp = contains ({" ==" , " !=" , " <" , " >" , " >=" , " <=" }, opStr );
682679 // Comparison must be the same type
683680 if (compareOp && lhs.valueType != rhs.valueType )
684681 return ValueFlow::Value::unknown ();
685682 // Only add, subtract, and compare for non-integers
686- if (!compareOp && !contains ({" +" , " -" }, op ) && !lhs.isIntValue () && !rhs.isIntValue ())
683+ if (!compareOp && !contains ({" +" , " -" }, opStr ) && !lhs.isIntValue () && !rhs.isIntValue ())
687684 return ValueFlow::Value::unknown ();
688685 // Both can't be iterators for non-compare
689686 if (!compareOp && lhs.isIteratorValue () && rhs.isIteratorValue ())
@@ -701,10 +698,10 @@ static ValueFlow::Value evaluate(const std::string& op, const ValueFlow::Value&
701698 result.valueType = ValueFlow::Value::ValueType::INT;
702699 }
703700 bool error = false ;
704- result.intvalue = calculate (op , lhs.intvalue , rhs.intvalue , &error);
701+ result.intvalue = calculate (opStr , lhs.intvalue , rhs.intvalue , &error);
705702 if (error)
706703 return ValueFlow::Value::unknown ();
707- if (result.isImpossible () && op == " !=" ) {
704+ if (result.isImpossible () && opStr == " !=" ) {
708705 if (isTrue (result)) {
709706 result.intvalue = 1 ;
710707 } else if (isFalse (result)) {
@@ -1501,7 +1498,7 @@ namespace {
15011498 if (!pm->hasValue (expr->astOperand1 ()->exprId ()))
15021499 return unknown ();
15031500 ValueFlow::Value& lhs = pm->at (expr->astOperand1 ()->exprId ());
1504- rhs = evaluate (removeAssign ( expr-> str ()) , lhs, rhs);
1501+ rhs = evaluate (expr, lhs, rhs, /* removeAssign */ true );
15051502 if (lhs.isIntValue ())
15061503 ValueFlow::Value::visitValue (rhs, std::bind (assign{}, std::ref (lhs.intvalue ), std::placeholders::_1));
15071504 else if (lhs.isFloatValue ())
@@ -1565,7 +1562,7 @@ namespace {
15651562 ValueFlow::Value rhs = execute (expr->astOperand2 ());
15661563 if (rhs.isUninitValue ())
15671564 return unknown ();
1568- ValueFlow::Value r = evaluate (expr-> str () , lhs, rhs);
1565+ ValueFlow::Value r = evaluate (expr, lhs, rhs);
15691566 if (expr->isComparisonOp () && (r.isUninitValue () || r.isImpossible ())) {
15701567 if (rhs.isIntValue () && !expr->astOperand1 ()->values ().empty ()) {
15711568 std::vector<ValueFlow::Value> result = infer (makeIntegralInferModel (),
0 commit comments