| 4038 | } |
| 4039 | |
| 4040 | static std::list<ValueFlow::Value> truncateValues(std::list<ValueFlow::Value> values, |
| 4041 | const ValueType* dst, |
| 4042 | const ValueType* src, |
| 4043 | const Settings& settings) |
| 4044 | { |
| 4045 | if (!dst || !dst->isIntegral()) |
| 4046 | return values; |
| 4047 | |
| 4048 | const size_t sz = dst->getSizeOf(settings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointer); |
| 4049 | |
| 4050 | if (src) { |
| 4051 | const size_t osz = src->getSizeOf(settings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointer); |
| 4052 | if (osz >= sz && dst->sign == ValueType::Sign::SIGNED && src->sign == ValueType::Sign::UNSIGNED) { |
| 4053 | values.remove_if([&](const ValueFlow::Value& value) { |
| 4054 | if (!value.isIntValue()) |
| 4055 | return false; |
| 4056 | if (!value.isImpossible()) |
| 4057 | return false; |
| 4058 | if (value.bound != ValueFlow::Value::Bound::Upper) |
| 4059 | return false; |
| 4060 | if (osz == sz && value.intvalue < 0) |
| 4061 | return true; |
| 4062 | if (osz > sz) |
| 4063 | return true; |
| 4064 | return false; |
| 4065 | }); |
| 4066 | } |
| 4067 | } |
| 4068 | |
| 4069 | for (ValueFlow::Value &value : values) { |
| 4070 | // Don't truncate impossible values since those can be outside of the valid range |
| 4071 | if (value.isImpossible()) |
| 4072 | continue; |
| 4073 | if (value.isFloatValue()) { |
| 4074 | value.intvalue = static_cast<MathLib::bigint>(value.floatValue); |
| 4075 | value.valueType = ValueFlow::Value::ValueType::INT; |
| 4076 | } |
| 4077 | |
| 4078 | if (value.isIntValue() && sz > 0 && sz < sizeof(MathLib::biguint)) |
| 4079 | value.intvalue = ValueFlow::truncateIntValue(value.intvalue, sz, dst->sign); |
| 4080 | } |
| 4081 | return values; |
| 4082 | } |
| 4083 | |
| 4084 | static bool isVariableInit(const Token *tok) |
| 4085 | { |
no test coverage detected