aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Kirchner <daniel@ekpyron.org>2018-11-06 06:52:45 +0800
committerDaniel Kirchner <daniel@ekpyron.org>2018-11-06 17:52:10 +0800
commite036133d1be1ac87af29ce145052884c2c025ffa (patch)
tree71a950f55cec1f9355313dcba66c1383cadee948
parent88aee34c22d86a004848ae8bdc818b5168dd94cb (diff)
downloaddexon-solidity-e036133d1be1ac87af29ce145052884c2c025ffa.tar
dexon-solidity-e036133d1be1ac87af29ce145052884c2c025ffa.tar.gz
dexon-solidity-e036133d1be1ac87af29ce145052884c2c025ffa.tar.bz2
dexon-solidity-e036133d1be1ac87af29ce145052884c2c025ffa.tar.lz
dexon-solidity-e036133d1be1ac87af29ce145052884c2c025ffa.tar.xz
dexon-solidity-e036133d1be1ac87af29ce145052884c2c025ffa.tar.zst
dexon-solidity-e036133d1be1ac87af29ce145052884c2c025ffa.zip
Fix negative denominator in ``boost::rational`` during exponentiation.
-rw-r--r--libsolidity/ast/Types.cpp4
-rw-r--r--libsolidity/ast/Types.h9
-rw-r--r--test/libsolidity/syntaxTests/types/rational_negative_numerator_negative_exp.sol5
3 files changed, 16 insertions, 2 deletions
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<FunctionType const>;
using TypePointers = std::vector<TypePointer>;
using rational = boost::rational<dev::bigint>;
+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;
+ }
+}