Skip to content

Commit 6ce96c7

Browse files
committed
Adds support for pointer history variables in function contracts
This adds support for history variables in function contracts. History variables are (1) declared and (2) assigned to the value that their corresponding variable has at function call time. Currently, only pointers are supported.
1 parent ffd4ccf commit 6ce96c7

File tree

33 files changed

+577
-16
lines changed

33 files changed

+577
-16
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include <stdio.h>
2+
3+
void bar(int *l) __CPROVER_assigns(*l) __CPROVER_requires(l != NULL)
4+
__CPROVER_ensures(__CPROVER_old(*l) == *l)
5+
{
6+
}
7+
8+
void foo(int *n) __CPROVER_assigns(*n) __CPROVER_requires(n != NULL)
9+
__CPROVER_ensures(__CPROVER_old(*n) == *n)
10+
{
11+
bar(n);
12+
}
13+
14+
int main()
15+
{
16+
int m;
17+
foo(&m);
18+
19+
return 0;
20+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
CORE
2+
main.c
3+
--enforce-contract foo --replace-call-with-contract bar
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
ASSUME tmp_cc\$\d != \(\(signed int \*\)NULL\)
8+
ASSERT n != \(\(signed int \*\)NULL\)
9+
ASSUME tmp_cc == \*n
10+
ASSERT tmp_cc\$\d == \*tmp_cc\$\d
11+
--
12+
--
13+
Verification:
14+
This test checks that history variables are supported for parameters of the
15+
the function under test. By using the --enforce-all-contracts flag,
16+
the post-condition (which contains the history variable) is asserted.
17+
In this case, this assertion should pass.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
void foo(int *x) __CPROVER_assigns(*x)
2+
__CPROVER_ensures(*x == __CPROVER_old(*x) + 5)
3+
{
4+
*x = *x + 5;
5+
}
6+
7+
int main()
8+
{
9+
int n;
10+
foo(&n);
11+
12+
return 0;
13+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
CORE
2+
main.c
3+
--enforce-all-contracts
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
ASSERT \*tmp_cc\$\d == tmp_cc\$\d \+ 5
8+
--
9+
--
10+
Verification:
11+
This test checks that history variables are supported for parameters of the
12+
the function under test. By using the --enforce-all-contracts flag,
13+
the post-condition (which contains the history variable) is asserted.
14+
In this case, this assertion should pass.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
void foo(int *x) __CPROVER_assigns(*x)
2+
__CPROVER_ensures(*x < __CPROVER_old(*x) + 5)
3+
{
4+
*x = *x + 5;
5+
}
6+
7+
int main()
8+
{
9+
int n;
10+
foo(&n);
11+
12+
return 0;
13+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
CORE
2+
main.c
3+
--enforce-all-contracts
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^VERIFICATION FAILED$
7+
ASSERT \*tmp_cc\$\d < tmp_cc\$\d \+ 5
8+
--
9+
--
10+
Verification:
11+
This test checks that history variables are supported for parameters of the
12+
the function under test. By using the --enforce-all-contracts flag,
13+
the post-condition (which contains the history variable) is asserted.
14+
In this case, this assertion should fail.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include <limits.h>
2+
3+
void foo(int *x) __CPROVER_assigns(*x)
4+
__CPROVER_requires(*x > 0 && *x < INT_MAX - 5) __CPROVER_ensures(
5+
*x >= __CPROVER_old(*x) + 4 && *x <= __CPROVER_old(*x) + 6)
6+
{
7+
*x = *x + 5;
8+
}
9+
10+
int main()
11+
{
12+
int n;
13+
foo(&n);
14+
15+
return 0;
16+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
CORE
2+
main.c
3+
--enforce-all-contracts
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
ASSERT tmp_if_expr\$\d
8+
--
9+
--
10+
Verification:
11+
This test checks that history variables are supported in the case where a
12+
history variable is referred to multiple times within an ensures clause.
13+
By using the --enforce-all-contracts flag, the post-condition (which contains
14+
the history variable) is asserted. In this case, this assertion should pass.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
void foo(int *x, int *y) __CPROVER_assigns(*x, *y)
2+
__CPROVER_ensures(*x == __CPROVER_old(*y) + 1 && *y == __CPROVER_old(*x) + 2)
3+
{
4+
int x_initial = *x;
5+
*x = *y + 1;
6+
*y = x_initial + 2;
7+
}
8+
9+
int main()
10+
{
11+
int x, y;
12+
foo(&x, &y);
13+
14+
return 0;
15+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
CORE
2+
main.c
3+
--enforce-all-contracts
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
ASSERT tmp_if_expr
8+
--
9+
--
10+
Verification:
11+
This test checks that history variables are supported in the case where the
12+
function under test has multiple parameters. By using the
13+
--enforce-all-contracts flag, the post-condition (which contains the history
14+
variables) is asserted. In this case, this assertion should pass.

0 commit comments

Comments
 (0)