diff --git a/Changelog.md b/Changelog.md index b2f9bf051..5a7a2d1d0 100644 --- a/Changelog.md +++ b/Changelog.md @@ -94,6 +94,7 @@ Bugfixes: * Type Checker: Allow assignments to local variables of mapping types. * Type Checker: Consider fixed size arrays when checking for recursive structs. * Type Checker: Fix crashes in erroneous tuple assignments in which the type of the right hand side cannot be determined. + * Type Checker: Fix freeze for negative fixed-point literals very close to ``0``, such as ``-1e-100``. * Type Checker: Report error when using structs in events without experimental ABIEncoderV2. This used to crash or log the wrong values. * Type System: Allow arbitrary exponents for literals with a mantissa of zero. diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 2dcfda42a..21631693e 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -1263,7 +1263,8 @@ shared_ptr RationalNumberType::fixedPointType() const return shared_ptr(); // This means we round towards zero for positive and negative values. bigint v = value.numerator() / value.denominator(); - if (negative) + + if (negative && v != 0) // modify value to satisfy bit requirements for negative numbers: // add one bit for sign and decrement because negative numbers can be larger v = (v - 1) << 1; diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index 3b57109d0..787c9360b 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -446,7 +446,8 @@ public: /// @returns the smallest integer type that can hold the value or an empty pointer if not possible. std::shared_ptr integerType() const; - /// @returns the smallest fixed type that can hold the value or incurs the least precision loss. + /// @returns the smallest fixed type that can hold the value or incurs the least precision loss, + /// unless the value was truncated, then a suitable type will be chosen to indicate such event. /// If the integer part does not fit, returns an empty pointer. std::shared_ptr fixedPointType() const; diff --git a/test/libsolidity/syntaxTests/types/too_small_negative_numbers.sol b/test/libsolidity/syntaxTests/types/too_small_negative_numbers.sol new file mode 100644 index 000000000..66bd9a8ea --- /dev/null +++ b/test/libsolidity/syntaxTests/types/too_small_negative_numbers.sol @@ -0,0 +1,4 @@ +contract C { + fixed8x80 a = -1e-100; +} +// ----