From 4c3e78d0462c27f5d7481352f0396e31349008de Mon Sep 17 00:00:00 2001 From: Djordje Mijovic Date: Tue, 12 May 2020 00:06:25 +0200 Subject: [PATCH] Disallowing shifts by signed types --- Changelog.md | 1 + docs/070-breaking-changes.rst | 2 ++ docs/types/value-types.rst | 6 ++--- libsolidity/ast/Types.cpp | 2 +- test/compilationTests/gnosis/Utils/Math.sol | 8 +++--- .../shifts/shift_negative_rvalue.sol | 15 ----------- .../shift_negative_rvalue_assignment.sol | 17 ------------ .../semanticTests/shifts/shift_overflow.sol | 6 ++--- .../shifts/shift_right_assignment_signed.sol | 14 ---------- .../shifts/shift_right_negative_lvalue.sol | 26 +++++++++---------- ...shift_right_negative_lvalue_assignment.sol | 26 +++++++++---------- .../shift_right_negative_lvalue_int16.sol | 26 +++++++++---------- .../shift_right_negative_lvalue_int32.sol | 26 +++++++++---------- .../shift_right_negative_lvalue_int8.sol | 26 +++++++++---------- ...right_negative_lvalue_signextend_int16.sol | 12 ++++----- ...ht_negative_lvalue_signextend_int16_v2.sol | 12 ++++----- ...right_negative_lvalue_signextend_int32.sol | 12 ++++----- ...ht_negative_lvalue_signextend_int32_v2.sol | 12 ++++----- ..._right_negative_lvalue_signextend_int8.sol | 12 ++++----- ...ght_negative_lvalue_signextend_int8_v2.sol | 12 ++++----- .../shifts/shift_signed_cleanup_amount.sol | 16 ------------ .../shift_underflow_negative_rvalue.sol | 15 +++++++++++ .../shifts/shift_singed_rvalue.sol | 11 ++++++++ 23 files changed, 141 insertions(+), 174 deletions(-) delete mode 100644 test/libsolidity/semanticTests/shifts/shift_negative_rvalue.sol delete mode 100644 test/libsolidity/semanticTests/shifts/shift_negative_rvalue_assignment.sol delete mode 100644 test/libsolidity/semanticTests/shifts/shift_right_assignment_signed.sol delete mode 100644 test/libsolidity/semanticTests/shifts/shift_signed_cleanup_amount.sol create mode 100644 test/libsolidity/semanticTests/shifts/shift_underflow_negative_rvalue.sol create mode 100644 test/libsolidity/syntaxTests/shifts/shift_singed_rvalue.sol diff --git a/Changelog.md b/Changelog.md index 7e9e3c3be..0d638e0f6 100644 --- a/Changelog.md +++ b/Changelog.md @@ -5,6 +5,7 @@ Breaking changes: * Deprecated dot syntax for `value` and `gas`. * Deprecated the identifier `now`. * JSON AST: Removes members with ``null`` value from JSON output. + * Type Checker: Disallow shifts by signed types. Language Features: diff --git a/docs/070-breaking-changes.rst b/docs/070-breaking-changes.rst index f273dcd0b..2971a25ea 100644 --- a/docs/070-breaking-changes.rst +++ b/docs/070-breaking-changes.rst @@ -16,3 +16,5 @@ This section gives detailed instructions on how to update prior code for every b * Change ``f.value(...)()`` to ``f{value: ...}()``. Similarly ``(new C).value(...)()`` to ``(new C){value: ...}()`` and ``f.gas(...)()`` to ``f{gas: ...}()``. * Change ``now`` to ``block.timestamp``. +* Change types of right operand in shift operators to unsigned types. For example change ``x >> (256 - y)`` to + ``x >> uint(256 - y)``. diff --git a/docs/types/value-types.rst b/docs/types/value-types.rst index bc70a3331..5d7adc7ca 100644 --- a/docs/types/value-types.rst +++ b/docs/types/value-types.rst @@ -64,11 +64,11 @@ Shifts ^^^^^^ The result of a shift operation has the type of the left operand, truncating the result to match the type. +Right operand must be unsigned type. Trying to shift by signed type will produce a compilation error. - For positive and negative ``x`` values, ``x << y`` is equivalent to ``x * 2**y``. - For positive ``x`` values, ``x >> y`` is equivalent to ``x / 2**y``. - For negative ``x`` values, ``x >> y`` is equivalent to ``(x + 1) / 2**y - 1`` (which is the same as dividing ``x`` by ``2**y`` while rounding down towards negative infinity). -- In all cases, shifting by a negative ``y`` throws a runtime exception. .. warning:: Before version ``0.5.0`` a right shift ``x >> y`` for negative ``x`` was equivalent to ``x / 2**y``, @@ -370,9 +370,9 @@ Operators: * Shift operators: ``<<`` (left shift), ``>>`` (right shift) * Index access: If ``x`` is of type ``bytesI``, then ``x[k]`` for ``0 <= k < I`` returns the ``k`` th byte (read-only). -The shifting operator works with any integer type as right operand (but +The shifting operator works with unsigned integer type as right operand (but returns the type of the left operand), which denotes the number of bits to shift by. -Shifting by a negative amount causes a runtime exception. +Shifting by a signed type will produce a compilation error. Members: diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index c25226379..ed41f3256 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -480,7 +480,7 @@ bool isValidShiftAndAmountType(Token _operator, Type const& _shiftAmountType) if (_operator == Token::SHR) return false; else if (IntegerType const* otherInt = dynamic_cast(&_shiftAmountType)) - return true; + return !otherInt->isSigned(); else if (RationalNumberType const* otherRat = dynamic_cast(&_shiftAmountType)) return !otherRat->isFractional() && otherRat->integerType() && !otherRat->integerType()->isSigned(); else diff --git a/test/compilationTests/gnosis/Utils/Math.sol b/test/compilationTests/gnosis/Utils/Math.sol index 090c935ec..bcae29b6a 100644 --- a/test/compilationTests/gnosis/Utils/Math.sol +++ b/test/compilationTests/gnosis/Utils/Math.sol @@ -94,12 +94,12 @@ library Math { zpow = zpow * z / ONE; result += 0x9c7 * zpow / ONE; if (shift >= 0) { - if (result >> (256-shift) > 0) - return (2**256-1); - return result << shift; + if (result >> uint(256 - shift) > 0) + return (2 ** 256 - 1); + return result << uint(shift); } else - return result >> (-shift); + return result >> uint(-shift); } /// @dev Returns natural logarithm value of given x diff --git a/test/libsolidity/semanticTests/shifts/shift_negative_rvalue.sol b/test/libsolidity/semanticTests/shifts/shift_negative_rvalue.sol deleted file mode 100644 index 611458246..000000000 --- a/test/libsolidity/semanticTests/shifts/shift_negative_rvalue.sol +++ /dev/null @@ -1,15 +0,0 @@ -contract C { - function f(int256 a, int256 b) public returns (int256) { - return a << b; - } - - function g(int256 a, int256 b) public returns (int256) { - return a >> b; - } -} - -// ==== -// compileViaYul: also -// ---- -// f(int256,int256): 1, -1 -> FAILURE -// g(int256,int256): 1, -1 -> FAILURE diff --git a/test/libsolidity/semanticTests/shifts/shift_negative_rvalue_assignment.sol b/test/libsolidity/semanticTests/shifts/shift_negative_rvalue_assignment.sol deleted file mode 100644 index 623a715ec..000000000 --- a/test/libsolidity/semanticTests/shifts/shift_negative_rvalue_assignment.sol +++ /dev/null @@ -1,17 +0,0 @@ -contract C { - function f(int256 a, int256 b) public returns (int256) { - a <<= b; - return a; - } - - function g(int256 a, int256 b) public returns (int256) { - a >>= b; - return a; - } -} - -// ==== -// compileViaYul: also -// ---- -// f(int256,int256): 1, -1 -> FAILURE -// g(int256,int256): 1, -1 -> FAILURE diff --git a/test/libsolidity/semanticTests/shifts/shift_overflow.sol b/test/libsolidity/semanticTests/shifts/shift_overflow.sol index 54f5fcc2b..c303d449e 100644 --- a/test/libsolidity/semanticTests/shifts/shift_overflow.sol +++ b/test/libsolidity/semanticTests/shifts/shift_overflow.sol @@ -3,7 +3,7 @@ contract C { return x << y; } - function leftS(int8 x, int8 y) public returns (int8) { + function leftS(int8 x, uint8 y) public returns (int8) { return x << y; } } @@ -14,5 +14,5 @@ contract C { // leftU(uint8,uint8): 255, 8 -> 0 // leftU(uint8,uint8): 255, 1 -> 254 // leftU(uint8,uint8): 255, 0 -> 255 -// leftS(int8,int8): 1, 7 -> -128 # Result is -128 and output is sign-extended, not zero-padded. # -// leftS(int8,int8): 1, 6 -> 64 +// leftS(int8,uint8): 1, 7 -> -128 # Result is -128 and output is sign-extended, not zero-padded. # +// leftS(int8,uint8): 1, 6 -> 64 diff --git a/test/libsolidity/semanticTests/shifts/shift_right_assignment_signed.sol b/test/libsolidity/semanticTests/shifts/shift_right_assignment_signed.sol deleted file mode 100644 index 5b8494167..000000000 --- a/test/libsolidity/semanticTests/shifts/shift_right_assignment_signed.sol +++ /dev/null @@ -1,14 +0,0 @@ -contract C { - function f(int256 a, int256 b) public returns (int256) { - a >>= b; - return a; - } -} - -// ==== -// compileViaYul: also -// ---- -// f(int256,int256): 0x4266, 0x0 -> 0x4266 -// f(int256,int256): 0x4266, 0x8 -> 0x42 -// f(int256,int256): 0x4266, 0x10 -> 0 -// f(int256,int256): 0x4266, 0x11 -> 0 diff --git a/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue.sol b/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue.sol index 2bac06e6e..013379d97 100644 --- a/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue.sol +++ b/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue.sol @@ -1,5 +1,5 @@ contract C { - function f(int256 a, int256 b) public returns (int256) { + function f(int256 a, uint256 b) public returns (int256) { return a >> b; } } @@ -7,15 +7,15 @@ contract C { // ==== // compileViaYul: also // ---- -// f(int256,int256): -4266, 0 -> -4266 -// f(int256,int256): -4266, 1 -> -2133 -// f(int256,int256): -4266, 4 -> -267 -// f(int256,int256): -4266, 8 -> -17 -// f(int256,int256): -4266, 16 -> -1 -// f(int256,int256): -4266, 17 -> -1 -// f(int256,int256): -4267, 0 -> -4267 -// f(int256,int256): -4267, 1 -> -2134 -// f(int256,int256): -4267, 4 -> -267 -// f(int256,int256): -4267, 8 -> -17 -// f(int256,int256): -4267, 16 -> -1 -// f(int256,int256): -4267, 17 -> -1 +// f(int256,uint256): -4266, 0 -> -4266 +// f(int256,uint256): -4266, 1 -> -2133 +// f(int256,uint256): -4266, 4 -> -267 +// f(int256,uint256): -4266, 8 -> -17 +// f(int256,uint256): -4266, 16 -> -1 +// f(int256,uint256): -4266, 17 -> -1 +// f(int256,uint256): -4267, 0 -> -4267 +// f(int256,uint256): -4267, 1 -> -2134 +// f(int256,uint256): -4267, 4 -> -267 +// f(int256,uint256): -4267, 8 -> -17 +// f(int256,uint256): -4267, 16 -> -1 +// f(int256,uint256): -4267, 17 -> -1 diff --git a/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_assignment.sol b/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_assignment.sol index 4fecffda4..2109f47d3 100644 --- a/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_assignment.sol +++ b/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_assignment.sol @@ -1,5 +1,5 @@ contract C { - function f(int256 a, int256 b) public returns (int256) { + function f(int256 a, uint256 b) public returns (int256) { a >>= b; return a; } @@ -8,15 +8,15 @@ contract C { // ==== // compileViaYul: also // ---- -// f(int256,int256): -4266, 0 -> -4266 -// f(int256,int256): -4266, 1 -> -2133 -// f(int256,int256): -4266, 4 -> -267 -// f(int256,int256): -4266, 8 -> -17 -// f(int256,int256): -4266, 16 -> -1 -// f(int256,int256): -4266, 17 -> -1 -// f(int256,int256): -4267, 0 -> -4267 -// f(int256,int256): -4267, 1 -> -2134 -// f(int256,int256): -4267, 4 -> -267 -// f(int256,int256): -4267, 8 -> -17 -// f(int256,int256): -4267, 16 -> -1 -// f(int256,int256): -4267, 17 -> -1 +// f(int256,uint256): -4266, 0 -> -4266 +// f(int256,uint256): -4266, 1 -> -2133 +// f(int256,uint256): -4266, 4 -> -267 +// f(int256,uint256): -4266, 8 -> -17 +// f(int256,uint256): -4266, 16 -> -1 +// f(int256,uint256): -4266, 17 -> -1 +// f(int256,uint256): -4267, 0 -> -4267 +// f(int256,uint256): -4267, 1 -> -2134 +// f(int256,uint256): -4267, 4 -> -267 +// f(int256,uint256): -4267, 8 -> -17 +// f(int256,uint256): -4267, 16 -> -1 +// f(int256,uint256): -4267, 17 -> -1 diff --git a/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_int16.sol b/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_int16.sol index 883f004d0..2132f13b1 100644 --- a/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_int16.sol +++ b/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_int16.sol @@ -1,5 +1,5 @@ contract C { - function f(int16 a, int16 b) public returns (int256) { + function f(int16 a, uint16 b) public returns (int256) { return a >> b; } } @@ -7,15 +7,15 @@ contract C { // ==== // compileViaYul: also // ---- -// f(int16,int16): -4266, 0 -> -4266 -// f(int16,int16): -4266, 1 -> -2133 -// f(int16,int16): -4266, 4 -> -267 -// f(int16,int16): -4266, 8 -> -17 -// f(int16,int16): -4266, 16 -> -1 -// f(int16,int16): -4266, 17 -> -1 -// f(int16,int16): -4267, 0 -> -4267 -// f(int16,int16): -4267, 1 -> -2134 -// f(int16,int16): -4267, 4 -> -267 -// f(int16,int16): -4267, 8 -> -17 -// f(int16,int16): -4267, 16 -> -1 -// f(int16,int16): -4267, 17 -> -1 +// f(int16,uint16): -4266, 0 -> -4266 +// f(int16,uint16): -4266, 1 -> -2133 +// f(int16,uint16): -4266, 4 -> -267 +// f(int16,uint16): -4266, 8 -> -17 +// f(int16,uint16): -4266, 16 -> -1 +// f(int16,uint16): -4266, 17 -> -1 +// f(int16,uint16): -4267, 0 -> -4267 +// f(int16,uint16): -4267, 1 -> -2134 +// f(int16,uint16): -4267, 4 -> -267 +// f(int16,uint16): -4267, 8 -> -17 +// f(int16,uint16): -4267, 16 -> -1 +// f(int16,uint16): -4267, 17 -> -1 diff --git a/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_int32.sol b/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_int32.sol index 4f689c015..8c944e26e 100644 --- a/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_int32.sol +++ b/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_int32.sol @@ -1,5 +1,5 @@ contract C { - function f(int32 a, int32 b) public returns (int256) { + function f(int32 a, uint32 b) public returns (int256) { return a >> b; } } @@ -7,15 +7,15 @@ contract C { // ==== // compileViaYul: also // ---- -// f(int32,int32): -4266, 0 -> -4266 -// f(int32,int32): -4266, 1 -> -2133 -// f(int32,int32): -4266, 4 -> -267 -// f(int32,int32): -4266, 8 -> -17 -// f(int32,int32): -4266, 16 -> -1 -// f(int32,int32): -4266, 17 -> -1 -// f(int32,int32): -4267, 0 -> -4267 -// f(int32,int32): -4267, 1 -> -2134 -// f(int32,int32): -4267, 4 -> -267 -// f(int32,int32): -4267, 8 -> -17 -// f(int32,int32): -4267, 16 -> -1 -// f(int32,int32): -4267, 17 -> -1 +// f(int32,uint32): -4266, 0 -> -4266 +// f(int32,uint32): -4266, 1 -> -2133 +// f(int32,uint32): -4266, 4 -> -267 +// f(int32,uint32): -4266, 8 -> -17 +// f(int32,uint32): -4266, 16 -> -1 +// f(int32,uint32): -4266, 17 -> -1 +// f(int32,uint32): -4267, 0 -> -4267 +// f(int32,uint32): -4267, 1 -> -2134 +// f(int32,uint32): -4267, 4 -> -267 +// f(int32,uint32): -4267, 8 -> -17 +// f(int32,uint32): -4267, 16 -> -1 +// f(int32,uint32): -4267, 17 -> -1 diff --git a/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_int8.sol b/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_int8.sol index 02f293e3c..d224a2379 100644 --- a/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_int8.sol +++ b/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_int8.sol @@ -1,5 +1,5 @@ contract C { - function f(int8 a, int8 b) public returns (int256) { + function f(int8 a, uint8 b) public returns (int256) { return a >> b; } } @@ -7,15 +7,15 @@ contract C { // ==== // compileViaYul: also // ---- -// f(int8,int8): -66, 0 -> -66 -// f(int8,int8): -66, 1 -> -33 -// f(int8,int8): -66, 4 -> -5 -// f(int8,int8): -66, 8 -> -1 -// f(int8,int8): -66, 16 -> -1 -// f(int8,int8): -66, 17 -> -1 -// f(int8,int8): -67, 0 -> -67 -// f(int8,int8): -67, 1 -> -34 -// f(int8,int8): -67, 4 -> -5 -// f(int8,int8): -67, 8 -> -1 -// f(int8,int8): -67, 16 -> -1 -// f(int8,int8): -67, 17 -> -1 +// f(int8,uint8): -66, 0 -> -66 +// f(int8,uint8): -66, 1 -> -33 +// f(int8,uint8): -66, 4 -> -5 +// f(int8,uint8): -66, 8 -> -1 +// f(int8,uint8): -66, 16 -> -1 +// f(int8,uint8): -66, 17 -> -1 +// f(int8,uint8): -67, 0 -> -67 +// f(int8,uint8): -67, 1 -> -34 +// f(int8,uint8): -67, 4 -> -5 +// f(int8,uint8): -67, 8 -> -1 +// f(int8,uint8): -67, 16 -> -1 +// f(int8,uint8): -67, 17 -> -1 diff --git a/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_signextend_int16.sol b/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_signextend_int16.sol index c59107f52..daa1ffb5f 100644 --- a/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_signextend_int16.sol +++ b/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_signextend_int16.sol @@ -1,13 +1,13 @@ contract C { - function f(int16 a, int16 b) public returns (int16) { + function f(int16 a, uint16 b) public returns (int16) { return a >> b; } } // ==== // ABIEncoderV1Only: true // ---- -// f(int16,int16): 0xff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99 -// f(int16,int16): 0xff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc -// f(int16,int16): 0xff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6 -// f(int16,int16): 0xff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9 -// f(int16,int16): 0xff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// f(int16,uint16): 0xff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99 +// f(int16,uint16): 0xff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc +// f(int16,uint16): 0xff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6 +// f(int16,uint16): 0xff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9 +// f(int16,uint16): 0xff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff diff --git a/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_signextend_int16_v2.sol b/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_signextend_int16_v2.sol index 850a89be3..5ffb50c23 100644 --- a/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_signextend_int16_v2.sol +++ b/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_signextend_int16_v2.sol @@ -2,15 +2,15 @@ pragma experimental ABIEncoderV2; contract C { - function f(int16 a, int16 b) public returns (int16) { + function f(int16 a, uint16 b) public returns (int16) { return a >> b; } } // ==== // compileViaYul: also // ---- -// f(int16,int16): 0xff99, 0x00 -> FAILURE -// f(int16,int16): 0xff99, 0x01 -> FAILURE -// f(int16,int16): 0xff99, 0x02 -> FAILURE -// f(int16,int16): 0xff99, 0x04 -> FAILURE -// f(int16,int16): 0xff99, 0x08 -> FAILURE +// f(int16,uint16): 0xff99, 0x00 -> FAILURE +// f(int16,uint16): 0xff99, 0x01 -> FAILURE +// f(int16,uint16): 0xff99, 0x02 -> FAILURE +// f(int16,uint16): 0xff99, 0x04 -> FAILURE +// f(int16,uint16): 0xff99, 0x08 -> FAILURE diff --git a/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_signextend_int32.sol b/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_signextend_int32.sol index 74e9d53b0..4070fe7e1 100644 --- a/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_signextend_int32.sol +++ b/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_signextend_int32.sol @@ -1,13 +1,13 @@ contract C { - function f(int32 a, int32 b) public returns (int32) { + function f(int32 a, uint32 b) public returns (int32) { return a >> b; } } // ==== // ABIEncoderV1Only: true // ---- -// f(int32,int32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99 -// f(int32,int32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc -// f(int32,int32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6 -// f(int32,int32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9 -// f(int32,int32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// f(int32,uint32): 0xffffff99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99 +// f(int32,uint32): 0xffffff99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc +// f(int32,uint32): 0xffffff99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6 +// f(int32,uint32): 0xffffff99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9 +// f(int32,uint32): 0xffffff99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff diff --git a/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_signextend_int32_v2.sol b/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_signextend_int32_v2.sol index d797531ec..a4cb461a1 100644 --- a/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_signextend_int32_v2.sol +++ b/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_signextend_int32_v2.sol @@ -2,15 +2,15 @@ pragma experimental ABIEncoderV2; contract C { - function f(int32 a, int32 b) public returns (int32) { + function f(int32 a, uint32 b) public returns (int32) { return a >> b; } } // ==== // compileViaYul: also // ---- -// f(int32,int32): 0xffffff99, 0x00 -> FAILURE -// f(int32,int32): 0xffffff99, 0x01 -> FAILURE -// f(int32,int32): 0xffffff99, 0x02 -> FAILURE -// f(int32,int32): 0xffffff99, 0x04 -> FAILURE -// f(int32,int32): 0xffffff99, 0x08 -> FAILURE +// f(int32,uint32): 0xffffff99, 0x00 -> FAILURE +// f(int32,uint32): 0xffffff99, 0x01 -> FAILURE +// f(int32,uint32): 0xffffff99, 0x02 -> FAILURE +// f(int32,uint32): 0xffffff99, 0x04 -> FAILURE +// f(int32,uint32): 0xffffff99, 0x08 -> FAILURE diff --git a/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_signextend_int8.sol b/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_signextend_int8.sol index 06dcf8eb5..95d983dcd 100644 --- a/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_signextend_int8.sol +++ b/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_signextend_int8.sol @@ -1,13 +1,13 @@ contract C { - function f(int8 a, int8 b) public returns (int8) { + function f(int8 a, uint8 b) public returns (int8) { return a >> b; } } // ==== // ABIEncoderV1Only: true // ---- -// f(int8,int8): 0x99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99 -// f(int8,int8): 0x99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc -// f(int8,int8): 0x99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6 -// f(int8,int8): 0x99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9 -// f(int8,int8): 0x99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// f(int8,uint8): 0x99, 0x00 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff99 +// f(int8,uint8): 0x99, 0x01 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcc +// f(int8,uint8): 0x99, 0x02 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe6 +// f(int8,uint8): 0x99, 0x04 -> 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9 +// f(int8,uint8): 0x99, 0x08 -> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff diff --git a/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_signextend_int8_v2.sol b/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_signextend_int8_v2.sol index ee485335d..f42f06773 100644 --- a/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_signextend_int8_v2.sol +++ b/test/libsolidity/semanticTests/shifts/shift_right_negative_lvalue_signextend_int8_v2.sol @@ -2,15 +2,15 @@ pragma experimental ABIEncoderV2; contract C { - function f(int8 a, int8 b) public returns (int8) { + function f(int8 a, uint8 b) public returns (int8) { return a >> b; } } // ==== // compileViaYul: also // ---- -// f(int8,int8): 0x99, 0x00 -> FAILURE -// f(int8,int8): 0x99, 0x01 -> FAILURE -// f(int8,int8): 0x99, 0x02 -> FAILURE -// f(int8,int8): 0x99, 0x04 -> FAILURE -// f(int8,int8): 0x99, 0x08 -> FAILURE +// f(int8,uint8): 0x99, 0x00 -> FAILURE +// f(int8,uint8): 0x99, 0x01 -> FAILURE +// f(int8,uint8): 0x99, 0x02 -> FAILURE +// f(int8,uint8): 0x99, 0x04 -> FAILURE +// f(int8,uint8): 0x99, 0x08 -> FAILURE diff --git a/test/libsolidity/semanticTests/shifts/shift_signed_cleanup_amount.sol b/test/libsolidity/semanticTests/shifts/shift_signed_cleanup_amount.sol deleted file mode 100644 index 72b8f69c8..000000000 --- a/test/libsolidity/semanticTests/shifts/shift_signed_cleanup_amount.sol +++ /dev/null @@ -1,16 +0,0 @@ -contract C { - function f(uint256 a, int8 b) public returns (uint256) { - assembly { b := 0xff } - return a << b; - } - function g(uint256 a, int8 b) public returns (uint256) { - assembly { b := 0xff } - return a >> b; - } -} - -// ==== -// compileViaYul: also -// ---- -// f(uint256,int8): 0x1234, 0x0 -> FAILURE -// g(uint256,int8): 0x1234, 0x0 -> FAILURE diff --git a/test/libsolidity/semanticTests/shifts/shift_underflow_negative_rvalue.sol b/test/libsolidity/semanticTests/shifts/shift_underflow_negative_rvalue.sol new file mode 100644 index 000000000..ad14558be --- /dev/null +++ b/test/libsolidity/semanticTests/shifts/shift_underflow_negative_rvalue.sol @@ -0,0 +1,15 @@ +contract C { + function f(int256 a, uint256 b) public returns (int256) { + return a << b; + } + + function g(int256 a, uint256 b) public returns (int256) { + return a >> b; + } +} + +// ==== +// compileViaYul: also +// ---- +// f(int256,uint256): 1, -1 -> 0 +// g(int256,uint256): 1, -1 -> 0 diff --git a/test/libsolidity/syntaxTests/shifts/shift_singed_rvalue.sol b/test/libsolidity/syntaxTests/shifts/shift_singed_rvalue.sol new file mode 100644 index 000000000..73b49f3df --- /dev/null +++ b/test/libsolidity/syntaxTests/shifts/shift_singed_rvalue.sol @@ -0,0 +1,11 @@ +contract C { + function f(int256 a, int256 b) public returns (int256) { + return a >> b; + } + function g(int256 a, int256 b) public returns (int256) { + return a >> (256 - b); + } +} +// ---- +// TypeError: (89-95): Operator >> not compatible with types int256 and int256 +// TypeError: (179-193): Operator >> not compatible with types int256 and int256