Disallowing shifts by signed types

This commit is contained in:
Djordje Mijovic
2020-05-26 10:18:21 +02:00
parent 69a028b49c
commit 4c3e78d046
23 changed files with 141 additions and 174 deletions
+4 -4
View File
@@ -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
@@ -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