MCPcopy Create free account
hub / github.com/cppcheck-opensource/cppcheck / evaluate

Function evaluate

lib/programmemory.cpp:650–716  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

648}
649
650static ValueFlow::Value evaluate(const Token* op, const ValueFlow::Value& lhs, const ValueFlow::Value& rhs, bool removeAssign = false)
651{
652 const std::string opStr = removeAssign ? op->str().substr(0, op->str().size() - 1) : op->str();
653 ValueFlow::Value result;
654 if (lhs.isImpossible() && rhs.isImpossible())
655 return ValueFlow::Value::unknown();
656 if (lhs.isImpossible() || rhs.isImpossible()) {
657 // noninvertible
658 if (contains({"%", "/", "&", "|"}, opStr))
659 return ValueFlow::Value::unknown();
660 result.setImpossible();
661 }
662 if (isNumericValue(lhs) && isNumericValue(rhs)) {
663 if (lhs.isFloatValue() || rhs.isFloatValue()) {
664 result.valueType = op->isArithmeticalOp() ? ValueFlow::Value::ValueType::FLOAT : ValueFlow::Value::ValueType::INT;
665 bool error = false;
666 result.floatValue = calculate(opStr, asFloat(lhs), asFloat(rhs), &error);
667 if (error)
668 return ValueFlow::Value::unknown();
669 return result;
670 }
671 }
672 // Must be integral types
673 if (!isIntegralValue(lhs) && !isIntegralValue(rhs))
674 return ValueFlow::Value::unknown();
675 // If not the same type then one must be int
676 if (lhs.valueType != rhs.valueType && !lhs.isIntValue() && !rhs.isIntValue())
677 return ValueFlow::Value::unknown();
678 const bool compareOp = op->isComparisonOp();
679 // Comparison must be the same type
680 if (compareOp && lhs.valueType != rhs.valueType)
681 return ValueFlow::Value::unknown();
682 // Only add, subtract, and compare for non-integers
683 if (!compareOp && !contains({"+", "-"}, opStr) && !lhs.isIntValue() && !rhs.isIntValue())
684 return ValueFlow::Value::unknown();
685 // Both can't be iterators for non-compare
686 if (!compareOp && lhs.isIteratorValue() && rhs.isIteratorValue())
687 return ValueFlow::Value::unknown();
688 // Symbolic values must be in the same ring
689 if (lhs.isSymbolicValue() && rhs.isSymbolicValue() && lhs.tokvalue != rhs.tokvalue)
690 return ValueFlow::Value::unknown();
691 if (!lhs.isIntValue() && !compareOp) {
692 result.valueType = lhs.valueType;
693 result.tokvalue = lhs.tokvalue;
694 } else if (!rhs.isIntValue() && !compareOp) {
695 result.valueType = rhs.valueType;
696 result.tokvalue = rhs.tokvalue;
697 } else {
698 result.valueType = ValueFlow::Value::ValueType::INT;
699 }
700 bool error = false;
701 result.intvalue = calculate(opStr, lhs.intvalue, rhs.intvalue, &error);
702 if (error)
703 return ValueFlow::Value::unknown();
704 if (result.isImpossible() && opStr == "!=") {
705 if (isTrue(result)) {
706 result.intvalue = 1;
707 } else if (isFalse(result)) {

Callers 1

executeImplMethod · 0.70

Calls 12

unknownFunction · 0.85
containsFunction · 0.85
isNumericValueFunction · 0.85
calculateFunction · 0.85
asFloatFunction · 0.85
isIntegralValueFunction · 0.85
isTrueFunction · 0.85
isFalseFunction · 0.85
isImpossibleMethod · 0.80
isArithmeticalOpMethod · 0.80
strMethod · 0.45
sizeMethod · 0.45

Tested by

no test coverage detected