aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog.md1
-rw-r--r--libsolidity/ast/Types.cpp3
-rw-r--r--libsolidity/ast/Types.h3
-rw-r--r--test/libsolidity/syntaxTests/types/too_small_negative_numbers.sol4
4 files changed, 9 insertions, 2 deletions
diff --git a/Changelog.md b/Changelog.md
index 7cbdc764..2f4ce1f9 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -102,6 +102,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 9e815ca8..68c201a8 100644
--- a/libsolidity/ast/Types.cpp
+++ b/libsolidity/ast/Types.cpp
@@ -1278,7 +1278,8 @@ shared_ptr<FixedPointType const> RationalNumberType::fixedPointType() const
return shared_ptr<FixedPointType const>();
// 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 cc96ac4b..34f862c3 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> 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> 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 00000000..66bd9a8e
--- /dev/null
+++ b/test/libsolidity/syntaxTests/types/too_small_negative_numbers.sol
@@ -0,0 +1,4 @@
+contract C {
+ fixed8x80 a = -1e-100;
+}
+// ----