mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Disallow bare fractional literals that incur precision loss.
This commit is contained in:
parent
5df275b846
commit
64408a9173
@ -1030,7 +1030,7 @@ TypeResult RationalNumberType::binaryOperatorResult(Token _operator, Type const*
|
||||
{
|
||||
if (_other->category() == Category::Integer || _other->category() == Category::FixedPoint)
|
||||
{
|
||||
if (isFractional() && !fixedPointType())
|
||||
if (isFractional() && !mobileType())
|
||||
return TypeResult::err("Literal too large or cannot be represented without precision loss.");
|
||||
else if (!isFractional() && !integerType())
|
||||
return TypeResult::err("Literal too large.");
|
||||
@ -1143,7 +1143,7 @@ u256 RationalNumberType::literalValue(Literal const*) const
|
||||
shiftedValue = m_value.numerator();
|
||||
else
|
||||
{
|
||||
auto fixed = fixedPointType();
|
||||
auto fixed = closestFixedPointType();
|
||||
solAssert(fixed, "Rational number cannot be represented as fixed point type.");
|
||||
unsigned fractionalDigits = fixed->fractionalDigits();
|
||||
shiftedValue = m_value.numerator() * boost::multiprecision::pow(bigint(10), fractionalDigits) / m_value.denominator();
|
||||
@ -1164,8 +1164,10 @@ Type const* RationalNumberType::mobileType() const
|
||||
{
|
||||
if (!isFractional())
|
||||
return integerType();
|
||||
else
|
||||
return fixedPointType();
|
||||
else if (auto const* fixed = closestFixedPointType())
|
||||
if (isImplicitlyConvertibleTo(*fixed))
|
||||
return fixed;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
IntegerType const* RationalNumberType::integerType() const
|
||||
@ -1184,7 +1186,7 @@ IntegerType const* RationalNumberType::integerType() const
|
||||
);
|
||||
}
|
||||
|
||||
FixedPointType const* RationalNumberType::fixedPointType() const
|
||||
FixedPointType const* RationalNumberType::closestFixedPointType() const
|
||||
{
|
||||
bool negative = (m_value < 0);
|
||||
unsigned fractionalDigits = 0;
|
||||
|
@ -580,7 +580,7 @@ public:
|
||||
/// If the integer part does not fit, returns an empty pointer.
|
||||
/// The rational number is not always implicitly convertible to the resulting type
|
||||
/// (for example if precision loss is required).
|
||||
FixedPointType const* fixedPointType() const;
|
||||
FixedPointType const* closestFixedPointType() const;
|
||||
|
||||
/// @returns true if the value is not an integer.
|
||||
bool isFractional() const { return m_value.denominator() != 1; }
|
||||
|
Loading…
Reference in New Issue
Block a user