From a7c2dba681409f72ae34581300e7cbfcea2f719c Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Fri, 22 Feb 2019 11:53:05 +0000 Subject: [PATCH] Document the boost multiprecision shift bug in RuleList --- libdevcore/CommonData.h | 6 ++++++ libevmasm/RuleList.h | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/libdevcore/CommonData.h b/libdevcore/CommonData.h index c39920dce..c157583a2 100644 --- a/libdevcore/CommonData.h +++ b/libdevcore/CommonData.h @@ -140,6 +140,12 @@ inline bytes toCompactBigEndian(uint8_t _val, unsigned _min = 0) return (_min || _val) ? bytes{ _val } : bytes{}; } +/// Workarounds shift left bug in boost <1.65.1. +template S bigintShiftLeftWorkaround(S const& _a, unsigned _b) +{ + return (S)(bigint(_a) << _b); +} + /// Convenience function for conversion of a u256 to hex inline std::string toHex(u256 val, HexPrefix prefix = HexPrefix::DontAdd) { diff --git a/libevmasm/RuleList.h b/libevmasm/RuleList.h index 7cdf5a96f..0208a379c 100644 --- a/libevmasm/RuleList.h +++ b/libevmasm/RuleList.h @@ -87,12 +87,12 @@ std::vector> simplificationRuleListPart1( return B.d(); unsigned testBit = unsigned(A.d()) * 8 + 7; u256 mask = (u256(1) << testBit) - 1; - return u256(boost::multiprecision::bit_test(B.d(), testBit) ? B.d() | ~mask : B.d() & mask); + return boost::multiprecision::bit_test(B.d(), testBit) ? B.d() | ~mask : B.d() & mask; }, false}, {{Instruction::SHL, {A, B}}, [=]{ if (A.d() > 255) return u256(0); - return u256(bigint(B.d()) << unsigned(A.d())); + return bigintShiftLeftWorkaround(B.d(), unsigned(A.d())); }, false}, {{Instruction::SHR, {A, B}}, [=]{ if (A.d() > 255)