From e036133d1be1ac87af29ce145052884c2c025ffa Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Mon, 5 Nov 2018 23:52:45 +0100 Subject: Fix negative denominator in ``boost::rational`` during exponentiation. --- libsolidity/ast/Types.cpp | 4 ++-- libsolidity/ast/Types.h | 9 +++++++++ .../types/rational_negative_numerator_negative_exp.sol | 5 +++++ 3 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 test/libsolidity/syntaxTests/types/rational_negative_numerator_negative_exp.sol diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index d5d11478..6c3863e6 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -1144,10 +1144,10 @@ TypePointer RationalNumberType::binaryOperatorResult(Token _operator, TypePointe bigint denominator = optimizedPow(m_value.denominator(), absExp); if (exp >= 0) - value = rational(numerator, denominator); + value = makeRational(numerator, denominator); else // invert - value = rational(denominator, numerator); + value = makeRational(denominator, numerator); } break; } diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index b764717f..24ace447 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -51,6 +51,15 @@ using FunctionTypePointer = std::shared_ptr; using TypePointers = std::vector; using rational = boost::rational; +inline rational makeRational(bigint const& _numerator, bigint const& _denominator) +{ + solAssert(_denominator != 0, "division by zero"); + // due to a bug in certain versions of boost the denominator has to be positive + if (_denominator < 0) + return rational(-_numerator, -_denominator); + else + return rational(_numerator, _denominator); +} enum class DataLocation { Storage, CallData, Memory }; diff --git a/test/libsolidity/syntaxTests/types/rational_negative_numerator_negative_exp.sol b/test/libsolidity/syntaxTests/types/rational_negative_numerator_negative_exp.sol new file mode 100644 index 00000000..b694992c --- /dev/null +++ b/test/libsolidity/syntaxTests/types/rational_negative_numerator_negative_exp.sol @@ -0,0 +1,5 @@ +contract C { + function f() public pure returns (int) { + return (-1 / 2) ** -1; + } +} -- cgit