[SMTChecker] Add loop support

This commit is contained in:
Leonardo Alt
2019-09-13 12:40:53 +02:00
parent 5d58c43a5c
commit e1c238e25f
34 changed files with 539 additions and 161 deletions
@@ -0,0 +1,19 @@
pragma experimental SMTChecker;
contract Simple {
uint[] a;
function f(uint n) public {
uint i;
while (i < n)
{
a[i] = i;
++i;
}
require(n > 1);
// Assertion is safe but current solver version cannot solve it.
// Keep test for next solver release.
assert(a[n-1] > a[n-2]);
}
}
// ----
// Warning: (273-296): Assertion violation happens here
@@ -0,0 +1,16 @@
pragma experimental SMTChecker;
contract Simple {
uint[] a;
function f(uint n) public {
uint i;
for (i = 0; i < n; ++i)
a[i] = i;
require(n > 1);
// Assertion is safe but current solver version cannot solve it.
// Keep test for next solver release.
assert(a[n-1] > a[n-2]);
}
}
// ----
// Warning: (267-290): Assertion violation happens here
@@ -0,0 +1,11 @@
pragma experimental SMTChecker;
contract Simple {
function f(uint x) public pure {
uint y;
require(x > 0);
while (y < x)
++y;
assert(y == x);
}
}
@@ -0,0 +1,10 @@
pragma experimental SMTChecker;
contract Simple {
function f(uint x) public pure {
uint y;
for (y = 0; y < x; ++y) {}
assert(y == x);
}
}
// ----
@@ -0,0 +1,17 @@
pragma experimental SMTChecker;
contract Simple {
function f() public pure {
uint x = 10;
uint y;
while (y < x)
{
++y;
x = 0;
while (x < 10)
++x;
assert(x == 10);
}
assert(y == x);
}
}
@@ -0,0 +1,14 @@
pragma experimental SMTChecker;
contract Simple {
function f() public pure {
uint x;
uint y;
for (x = 10; y < x; ++y)
{
for (x = 0; x < 10; ++x) {}
assert(x == 10);
}
assert(y == x);
}
}
@@ -15,4 +15,3 @@ contract C
}
// ----
// Warning: (150-155): Overflow (resulting value larger than 2**256 - 1) happens here
// Warning: (269-282): Assertion violation happens here
@@ -8,10 +8,12 @@ contract C
// Overflows due to resetting x.
x = x + 1;
}
// The assertion is true but x is touched and reset.
// Assertion is safe but current solver version cannot solve it.
// Keep test for next solver release.
assert(x > 0);
}
}
// ----
// Warning: (296-309): Error trying to invoke SMT solver.
// Warning: (176-181): Overflow (resulting value larger than 2**256 - 1) happens here
// Warning: (244-257): Assertion violation happens here
// Warning: (296-309): Assertion violation happens here
@@ -10,4 +10,3 @@ contract C {
}
}
// ----
// Warning: (213-226): Assertion violation happens here
@@ -18,5 +18,4 @@ contract LoopFor2 {
}
}
// ----
// Warning: (265-285): Assertion violation happens here
// Warning: (312-331): Assertion violation happens here
@@ -18,6 +18,5 @@ contract LoopFor2 {
}
}
// ----
// Warning: (266-286): Assertion violation happens here
// Warning: (290-309): Assertion violation happens here
// Warning: (313-332): Assertion violation happens here
@@ -15,4 +15,3 @@ contract C {
}
// ----
// Warning: (115-121): Unused local variable.
// Warning: (356-370): Assertion violation happens here
@@ -14,4 +14,3 @@ contract C
}
}
// ----
// Warning: (177-190): Assertion violation happens here
@@ -0,0 +1,21 @@
pragma experimental SMTChecker;
contract C
{
function f(uint x, bool b) public pure {
require(x < 10);
while (x < 10) {
if (b)
++x;
else {
x = 20;
break;
}
}
// Assertion is safe but break is unsupported for now
// so knowledge is erased.
assert(x >= 10);
}
}
// ----
// Warning: (274-289): Assertion violation happens here
@@ -0,0 +1,19 @@
pragma experimental SMTChecker;
contract C
{
function f(uint x, bool b) public pure {
require(x < 10);
while (x < 10) {
if (b)
++x;
else {
break;
}
}
// Fails because the loop might break.
assert(x >= 10);
}
}
// ----
// Warning: (218-233): Assertion violation happens here
@@ -0,0 +1,22 @@
pragma experimental SMTChecker;
contract C
{
function f(uint x, bool b) public pure {
require(x < 100);
while (x < 10) {
if (b) {
x = 15;
continue;
}
else
x = 20;
}
// Should be safe, but fails due to continue being unsupported
// and erasing all knowledge.
assert(x >= 15);
}
}
// ----
// Warning: (294-309): Assertion violation happens here
@@ -0,0 +1,21 @@
pragma experimental SMTChecker;
contract C
{
function f(uint x, bool b) public pure {
require(x < 100);
while (x < 10) {
if (b) {
x = 15;
continue;
}
else
x = 20;
}
// Fails due to the if.
assert(x >= 17);
}
}
// ----
// Warning: (223-238): Assertion violation happens here
@@ -0,0 +1,21 @@
pragma experimental SMTChecker;
contract C
{
function f(uint x, bool b) public pure {
require(x < 100);
while (x < 10) {
if (b)
x = x + 1;
else
x = 0;
}
// CHC proves it safe because
// 1- if it doesn't go in the loop in the first place, x >= 10
// 2- if it goes in the loop and b == true, x increases until >= 10
// 3- if it goes in the loop and b == false, it's an infinite loop, therefore
// the assertion and the error are unreachable.
assert(x > 0);
}
}
// ----
@@ -0,0 +1,13 @@
pragma experimental SMTChecker;
contract C {
function f(uint x) public pure {
x = 2;
while (x > 1) {
if (x > 10)
x = 2;
else
--x;
}
assert(x < 2);
}
}
@@ -0,0 +1,19 @@
pragma experimental SMTChecker;
contract C
{
function f() public pure {
uint x = 0;
while (x == 0) {
++x;
break;
++x;
}
// Assertion is safe but break is unsupported for now
// so knowledge is erased.
assert(x == 1);
}
}
// ----
// Warning: (128-131): Unreachable code.
// Warning: (224-238): Assertion violation happens here
@@ -0,0 +1,16 @@
pragma experimental SMTChecker;
contract C
{
function f(uint x) public pure {
while (x == 0) {
++x;
break;
++x;
}
assert(x == 2);
}
}
// ----
// Warning: (120-123): Unreachable code.
// Warning: (131-145): Assertion violation happens here
@@ -12,4 +12,3 @@ contract C {
}
}
// ----
// Warning: (158-172): Assertion violation happens here
@@ -13,11 +13,13 @@ contract LoopFor2 {
c[i] = b[i];
++i;
}
// Fails due to aliasing, since both b and c are
// memory references of same type.
assert(b[0] == c[0]);
assert(a[0] == 900);
assert(b[0] == 900);
}
}
// ----
// Warning: (274-294): Assertion violation happens here
// Warning: (321-340): Assertion violation happens here
// Warning: (362-382): Assertion violation happens here
// Warning: (409-428): Assertion violation happens here
@@ -20,5 +20,4 @@ contract LoopFor2 {
}
}
// ----
// Warning: (265-285): Assertion violation happens here
// Warning: (312-331): Assertion violation happens here
@@ -20,6 +20,5 @@ contract LoopFor2 {
}
}
// ----
// Warning: (266-286): Assertion violation happens here
// Warning: (290-309): Assertion violation happens here
// Warning: (313-332): Assertion violation happens here
@@ -8,4 +8,3 @@ contract C {
}
}
// ----
// Warning: (199-213): Assertion violation happens here
@@ -4,7 +4,6 @@
"smtlib2responses":
{
"0x047d0c67d7e03c5ac96ca227d1e19ba63257f4ab19cef30029413219ec8963af": "sat\n((|EVALEXPR_0| 0))\n",
"0x21d5b49d1416d788fe34b1d2a10a99ea92b007e17a977604afd7b2ff01a055cd": "unsat\n",
"0xada7569fb01a9b3e2823517ed40dcc99b11fb1e433e6e3ec8a8713f6f95753d3": "sat\n((|EVALEXPR_0| 1))\n"
}
}