Skip to content

Commit e645434

Browse files
authored
Merge pull request #6025 from ArenBabikian/ghost-variables
Supports history variables in function contracts
2 parents 8e95986 + 6ce96c7 commit e645434

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)