mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #8901 from mijovic/dissalowShiftsBySignedArguments
[BREAKING] Disallowing shifts by signed types
This commit is contained in:
commit
189d30b3ee
@ -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:
|
||||
|
||||
|
@ -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)``.
|
||||
|
@ -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:
|
||||
|
||||
|
@ -480,7 +480,7 @@ bool isValidShiftAndAmountType(Token _operator, Type const& _shiftAmountType)
|
||||
if (_operator == Token::SHR)
|
||||
return false;
|
||||
else if (IntegerType const* otherInt = dynamic_cast<decltype(otherInt)>(&_shiftAmountType))
|
||||
return true;
|
||||
return !otherInt->isSigned();
|
||||
else if (RationalNumberType const* otherRat = dynamic_cast<decltype(otherRat)>(&_shiftAmountType))
|
||||
return !otherRat->isFractional() && otherRat->integerType() && !otherRat->integerType()->isSigned();
|
||||
else
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
@ -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
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
11
test/libsolidity/syntaxTests/shifts/shift_singed_rvalue.sol
Normal file
11
test/libsolidity/syntaxTests/shifts/shift_singed_rvalue.sol
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user