Merge pull request #9854 from ethereum/bitwiseSmt

[SMTChecker] Support compound shifts and bitwise and, or, and xor
This commit is contained in:
Đorđe Mijović
2020-09-23 12:35:48 +02:00
committed by GitHub
26 changed files with 363 additions and 135 deletions
@@ -1,13 +0,0 @@
pragma experimental SMTChecker;
contract C {
function f(bool b) public pure {
uint v = 1;
if (b)
v &= 1;
assert(v == 1);
}
}
// ----
// Warning 6328: (116-130): Assertion violation happens here.
// Warning 9149: (106-112): Assertion checker does not yet implement this assignment operator.
@@ -0,0 +1,14 @@
pragma experimental SMTChecker;
contract C {
function f() public pure returns (byte) {
byte a = 0xff;
byte b = 0xf0;
a &= b;
assert(a == b);
a &= ~b;
assert(a != 0); // fails
}
}
// ----
// Warning 6328: (203-217): Assertion violation happens here.
@@ -0,0 +1,21 @@
pragma experimental SMTChecker;
contract C {
function f() public pure {
int8 x = 1;
int8 y = 0;
x &= y;
assert(x != 0); // fails
x = -1; y = 3;
y &= x;
assert(y == 3);
y = -1;
y &= x;
assert(y == -1);
y = 127;
x &= y;
assert(x == 127);
}
}
// ----
// Warning 6328: (114-128): Assertion violation happens here.
@@ -0,0 +1,33 @@
pragma experimental SMTChecker;
contract C {
function f() public pure {
uint v = 1;
v &= 1;
assert(v == 1);
v = 7;
v &= 3;
assert(v != 3); // fails, as 7 & 3 = 3
uint c = 0;
c &= v;
assert(c == 0);
uint8 x = 0xff;
uint16 y = 0xffff;
y &= x;
assert(y == 0xff);
assert(y == 0xffff); // fails
y = 0xffff;
x = 0xff;
y &= y | x;
assert(y == 0xffff);
assert(y == 0xff); // fails
}
}
// ----
// Warning 6328: (177-191): Assertion violation happens here.
// Warning 6328: (380-399): Assertion violation happens here.
// Warning 6328: (506-523): Assertion violation happens here.
@@ -1,10 +0,0 @@
pragma experimental SMTChecker;
contract C {
int[1] c;
function f(bool b) public {
if (b)
c[0] |= 1;
}
}
// ----
// Warning 9149: (97-106): Assertion checker does not yet implement this assignment operator.
@@ -1,10 +0,0 @@
pragma experimental SMTChecker;
contract C {
int[1][20] c;
function f(bool b) public {
if (b)
c[10][0] |= 1;
}
}
// ----
// Warning 9149: (101-114): Assertion checker does not yet implement this assignment operator.
@@ -1,13 +0,0 @@
pragma experimental SMTChecker;
contract C {
struct S {
uint x;
}
S s;
function f(bool b) public {
if (b)
s.x |= 1;
}
}
// ----
// Warning 9149: (117-125): Assertion checker does not yet implement this assignment operator.
@@ -1,13 +0,0 @@
pragma experimental SMTChecker;
contract C {
struct S {
uint[] x;
}
S s;
function f(bool b) public {
if (b)
s.x[2] |= 1;
}
}
// ----
// Warning 9149: (119-130): Assertion checker does not yet implement this assignment operator.
@@ -0,0 +1,14 @@
pragma experimental SMTChecker;
contract C {
function f() public pure returns (byte) {
byte a = 0xff;
byte b = 0xf0;
b |= a;
assert(a == b);
a |= ~b;
assert(a == 0); // fails
}
}
// ----
// Warning 6328: (203-217): Assertion violation happens here.
@@ -0,0 +1,21 @@
pragma experimental SMTChecker;
contract C {
function f() public pure {
int8 x = 1;
int8 y = 0;
x |= y;
assert(x == 0); // fails
x = -1; y = 3;
x |= y;
assert(x == -1);
x = 4;
y |= x;
assert(y == 7);
y = 127;
x |= y;
assert(x == 127);
}
}
// ----
// Warning 6328: (114-128): Assertion violation happens here.
@@ -0,0 +1,11 @@
pragma experimental SMTChecker;
contract C {
int[1][20] c;
function f(bool b) public {
require(c[10][0] == 0);
if (b)
c[10][0] |= 1;
assert(c[10][0] == 0 || c[10][0] == 1);
}
}
// ----
@@ -0,0 +1,29 @@
pragma experimental SMTChecker;
contract C {
function f() public pure {
uint v = 7;
v |= 3;
assert(v != 7); // fails, as 7 | 3 = 7
uint c = 0;
c |= v;
assert(c == 7);
uint16 x = 0xff;
uint16 y = 0xffff;
y |= x;
assert(y == 0xff); // fails
assert(y == 0xffff);
y = 0xf1ff;
x = 0xff00;
x |= y & x;
assert(y == 0xffff); // fails
assert(x == 0xff00);
}
}
// ----
// Warning 6328: (121-135): Assertion violation happens here.
// Warning 6328: (298-315): Assertion violation happens here.
// Warning 6328: (424-443): Assertion violation happens here.
@@ -0,0 +1,11 @@
pragma experimental SMTChecker;
contract C {
uint[1] c;
function f(bool b) public {
require(c[0] == 0);
if (b)
c[0] |= 1;
assert(c[0] <= 1);
}
}
// ----
@@ -0,0 +1,14 @@
pragma experimental SMTChecker;
contract C {
struct S {
uint[] x;
}
S s;
function f(bool b) public {
if (b)
s.x[2] |= 1;
assert(s.x[2] != 1);
}
}
// ----
// Warning 6328: (173-192): Assertion violation happens here.
@@ -0,0 +1,12 @@
pragma experimental SMTChecker;
contract C {
struct S {
uint x;
}
S s;
function f(bool b) public {
s.x |= b ? 1 : 2;
assert(s.x > 0);
}
}
// ----
@@ -1,13 +0,0 @@
pragma experimental SMTChecker;
contract C {
function f(bool b) public pure {
uint v = 0;
if (b)
v ^= 1;
assert(v == 1);
}
}
// ----
// Warning 6328: (116-130): Assertion violation happens here.
// Warning 9149: (106-112): Assertion checker does not yet implement this assignment operator.
@@ -0,0 +1,14 @@
pragma experimental SMTChecker;
contract C {
function f() public pure returns (byte) {
byte a = 0xff;
byte b = 0xf0;
a ^= ~b;
assert(a == b);
a ^= ~b;
assert(a != 0xff); // fails
}
}
// ----
// Warning 6328: (204-221): Assertion violation happens here.
@@ -0,0 +1,18 @@
pragma experimental SMTChecker;
contract C {
function f() public pure {
int8 x = 1;
int8 y = 0;
x ^= y;
assert(x != 1); // fails
x = -1; y = 1;
x ^= y;
assert(x == -2);
x = 4;
y ^= x;
assert(y == 5);
}
}
// ----
// Warning 6328: (114-128): Assertion violation happens here.
@@ -0,0 +1,29 @@
pragma experimental SMTChecker;
contract C {
function f() public pure {
uint v = 7;
v ^= 3;
assert(v != 4); // fails, as 7 ^ 3 = 4
uint c = 0;
c ^= v;
assert(c == 4);
uint16 x = 0xff;
uint16 y = 0xffff;
y ^= x;
assert(y == 0xff); // fails
assert(y == 0xff00);
y = 0xf1;
x = 0xff00;
y ^= x | y;
assert(y == 0xffff); // fails
assert(x == 0xff00);
}
}
// ----
// Warning 6328: (121-135): Assertion violation happens here.
// Warning 6328: (298-315): Assertion violation happens here.
// Warning 6328: (422-441): Assertion violation happens here.
@@ -9,5 +9,3 @@ contract C {
}
}
// ----
// Warning 6328: (123-136): Assertion violation happens here.
// Warning 9149: (112-119): Assertion checker does not yet implement this assignment operator.
@@ -10,4 +10,3 @@ contract C {
}
// ----
// Warning 6328: (117-130): Assertion violation happens here.
// Warning 9149: (106-113): Assertion checker does not yet implement this assignment operator.
@@ -0,0 +1,15 @@
pragma experimental SMTChecker;
contract C {
function f(uint256 a, uint256 b) internal pure returns (uint256) {
a <<= b;
return a;
}
function t() public pure {
assert(f(0x4266, 0x0) == 0x4266);
assert(f(0x4266, 0x8) == 0x426600);
assert(f(0x4266, 0xf0) == 0x4266000000000000000000000000000000000000000000000000000000000000);
assert(f(0x4266, 0x4266) == 0);
}
}
// ----
@@ -0,0 +1,15 @@
pragma experimental SMTChecker;
contract C {
function f(uint256 a, uint256 b) internal pure returns (uint256) {
a >>= b;
return a;
}
function t() public pure {
assert(f(0x4266, 0) == 0x4266);
assert(f(0x4266, 0x8) == 0x42);
assert(f(0x4266, 0x11) == 0);
assert(f(57896044618658097711785492504343953926634992332820282019728792003956564819968, 5) == 1809251394333065553493296640760748560207343510400633813116524750123642650624);
}
}
// ----