[SMTChecker] Support check/unchecked

This commit is contained in:
Leonardo Alt
2020-12-30 12:14:30 +01:00
parent eb05826857
commit 78d55e6b4a
74 changed files with 765 additions and 614 deletions
@@ -0,0 +1,12 @@
pragma experimental SMTChecker;
contract C {
function f() public pure returns (uint y) {
unchecked{{
uint max = type(uint).max;
uint x = max + 1; // overflow not reported
y = x;
}}
assert(y == 0);
}
}
@@ -0,0 +1,20 @@
pragma experimental SMTChecker;
contract C {
uint public x = msg.value - 10; // can underflow
constructor() payable {}
}
contract D {
function h() internal returns (uint) {
return msg.value - 10; // can underflow
}
function f() public {
unchecked {
h(); // unchecked here does not mean h does not underflow
}
}
}
// ----
// Warning 3944: (66-80): CHC: Underflow (resulting value less than 0) happens here.\nCounterexample:\nx = 0\n\n\n\nTransaction trace:\nconstructor()
// Warning 3944: (193-207): CHC: Underflow (resulting value less than 0) happens here.\nCounterexample:\n\n\n\n\nTransaction trace:\nconstructor()\nf()
@@ -0,0 +1,13 @@
pragma experimental SMTChecker;
contract C {
function add(uint16 a, uint16 b) public pure returns (uint16) {
return a + b; // can overflow
}
function f(uint16 a, uint16 b, uint16 c) public pure returns (uint16) {
unchecked { return add(a, b) + c; } // add can still overflow, `+ c` can't
}
}
// ----
// Warning 4984: (129-134): CHC: Overflow (resulting value larger than 65535) happens here.\nCounterexample:\n\na = 1\nb = 65535\n = 0\n\nTransaction trace:\nconstructor()\nadd(1, 65535)
@@ -0,0 +1,14 @@
pragma experimental SMTChecker;
contract C {
modifier add(uint16 a, uint16 b) {
unchecked { a + b; } // overflow not reported
_;
}
function f(uint16 a, uint16 b, uint16 c) public pure add(a, b) returns (uint16) {
return b + c; // can overflow
}
}
// ----
// Warning 4984: (258-263): CHC: Overflow (resulting value larger than 65535) happens here.\nCounterexample:\n\na = 65535\nb = 1\nc = 65535\n = 0\n\nTransaction trace:\nconstructor()\nf(65535, 1, 65535)
@@ -0,0 +1,13 @@
pragma experimental SMTChecker;
contract test {
function f() public pure returns (bool) {
int256 x = -2**255;
unchecked { assert(-x == x); }
assert(-x == x); // CHC apparently does not create an underflow target for unary minus
return true;
}
}
// ----
// Warning 6328: (143-158): CHC: Assertion violation happens here.\nCounterexample:\n\n\n = false\n\nTransaction trace:\nconstructor()\nf()
// Warning 2661: (150-152): BMC: Overflow (resulting value larger than 0x80 * 2**248 - 1) happens here.
@@ -0,0 +1,27 @@
pragma experimental SMTChecker;
contract C {
function o() public pure {
uint x = type(uint).max;
unchecked { ++x; }
assert(x == type(uint).min);
}
function u() public pure {
uint x = type(uint).min;
unchecked { --x; }
assert(x == type(uint).max);
}
function o_int() public pure {
int x = type(int).max;
unchecked { ++x; }
assert(x == type(int).min);
}
function u_int() public pure {
int x = type(int).min;
unchecked { --x; }
assert(x == type(int).max);
}
}
@@ -0,0 +1,18 @@
pragma experimental SMTChecker;
contract C {
function f(int a, int b) public pure returns (int) {
return a % b; // can div by 0
}
function g(bool _check) public pure returns (int) {
int x = type(int).min;
if (_check) {
return x / -1; // can overflow
} else {
unchecked { return x / -1; } // overflow not reported
}
}
}
// ----
// Warning 4281: (118-123): CHC: Division by zero happens here.\nCounterexample:\n\na = 0\nb = 0\n = 0\n\nTransaction trace:\nconstructor()\nf(0, 0)
// Warning 4984: (275-281): CHC: Overflow (resulting value larger than 0x80 * 2**248 - 1) happens here.\nCounterexample:\n\n_check = true\n = 0\n\nTransaction trace:\nconstructor()\ng(true)
@@ -0,0 +1,15 @@
pragma experimental SMTChecker;
contract C {
function add(uint16 a, uint16 b) public pure returns (uint16) {
unchecked {
return a + b; // overflow not reported
}
}
function f(uint16 a) public pure returns (uint16) {
return add(a, 0x100) + 0x100; // should overflow on `+ 0x100`
}
}
// ----
// Warning 4984: (273-294): CHC: Overflow (resulting value larger than 65535) happens here.\nCounterexample:\n\na = 65024\n = 0\n\nTransaction trace:\nconstructor()\nf(65024)
@@ -0,0 +1,20 @@
pragma experimental SMTChecker;
contract C {
function div(uint256 a, uint256 b) public pure returns (uint256) {
// Does not disable div by zero check
unchecked {
return a / b;
}
}
function mod(uint256 a, uint256 b) public pure returns (uint256) {
// Does not disable div by zero check
unchecked {
return a % b;
}
}
}
// ----
// Warning 4281: (202-207): CHC: Division by zero happens here.\nCounterexample:\n\na = 0\nb = 0\n = 0\n\nTransaction trace:\nconstructor()\ndiv(0, 0)
// Warning 4281: (382-387): CHC: Division by zero happens here.\nCounterexample:\n\na = 0\nb = 0\n = 0\n\nTransaction trace:\nconstructor()\nmod(0, 0)