Skip to content

Commit 3e0007f

Browse files
authored
Merge pull request #6197 from LongPham7/Long_internship
goto instrumentation for decreases clauses on loops
2 parents a7d4c3d + 00608b6 commit 3e0007f

File tree

21 files changed

+326
-37
lines changed

21 files changed

+326
-37
lines changed

regression/contracts/invar_check_multiple_loops/test.desc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ main.c
55
^SIGNAL=0$
66
^\[main.1\] .* Check loop invariant before entry: SUCCESS$
77
^\[main.2\] .* Check that loop invariant is preserved: SUCCESS$
8-
^\[main.3\] .* Check loop invariant before entry: SUCCESS$
9-
^\[main.4\] .* Check that loop invariant is preserved: SUCCESS$
8+
^\[main.3\] .* Check decreases clause on loop iteration: SUCCESS$
9+
^\[main.4\] .* Check loop invariant before entry: SUCCESS$
10+
^\[main.5\] .* Check that loop invariant is preserved: SUCCESS$
11+
^\[main.6\] .* Check decreases clause on loop iteration: SUCCESS$
1012
^\[main.assertion.1\] .* assertion x == y \+ 2 \* n: SUCCESS$
1113
^VERIFICATION SUCCESSFUL$
1214
--

regression/contracts/invar_check_nested_loops/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ int main()
77

88
for(int i = 0; i < n; ++i)
99
// clang-format off
10-
__CPROVER_loop_invariant(i <= n && s == i)
10+
__CPROVER_loop_invariant(0 <= i && i <= n && s == i)
1111
__CPROVER_decreases(n - i)
1212
// clang-format on
1313
{

regression/contracts/invar_check_nested_loops/test.desc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ main.c
44
^EXIT=0$
55
^SIGNAL=0$
66
^\[main.1\] .* Check loop invariant before entry: SUCCESS$
7-
^\[main.4\] .* Check that loop invariant is preserved: SUCCESS$
7+
^\[main.5\] .* Check that loop invariant is preserved: SUCCESS$
8+
^\[main.6\] .* Check decreases clause on loop iteration: SUCCESS$
89
^\[main.2\] .* Check loop invariant before entry: SUCCESS$
910
^\[main.3\] .* Check that loop invariant is preserved: SUCCESS$
11+
^\[main.4\] .* Check decreases clause on loop iteration: SUCCESS$
1012
^\[main.assertion.1\] .* assertion s == n: SUCCESS$
1113
^VERIFICATION SUCCESSFUL$
1214
--
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#define N 10
2+
3+
int foo(int i);
4+
5+
int main()
6+
{
7+
int i = 0;
8+
while(i != N)
9+
// clang-format off
10+
__CPROVER_loop_invariant(0 <= i && i <= N)
11+
__CPROVER_decreases(foo(i))
12+
// clang-format on
13+
{
14+
i++;
15+
}
16+
17+
return 0;
18+
}
19+
20+
int foo(int i)
21+
{
22+
return N - i;
23+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
CORE
2+
main.c
3+
--apply-loop-contracts
4+
^Decreases clause is not side-effect free. \(at: file main.c line .* function main\)$
5+
^EXIT=70$
6+
^SIGNAL=0$
7+
--
8+
--
9+
This test fails because the decreases clause contains a function call. Decreases
10+
clauses must not contain loops, since we want to ensure that the
11+
calculation of decreases clauses will terminate. To enforce this requirement,
12+
for now, we simply ban decreases clauses from containing function calls.
13+
In the future, we may allow function calls (but definitely not loops) to appear
14+
inside decreases clauses.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
int main()
2+
{
3+
unsigned i = 10;
4+
while(i != 0)
5+
// clang-format off
6+
__CPROVER_decreases(i)
7+
// clang-format on
8+
{
9+
i--;
10+
}
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+
--apply-loop-contracts
4+
activate-multi-line-match
5+
^The loop at file main.c line 4 function main does not have a loop invariant, but has a decreases clause. Hence, a default loop invariant \('true'\) is being used.$
6+
^\[main.1\].*Check loop invariant before entry: SUCCESS$
7+
^\[main.2\].*Check that loop invariant is preserved: SUCCESS$
8+
^\[main.3\].*Check decreases clause on loop iteration: SUCCESS$
9+
^EXIT=0$
10+
^SIGNAL=0$
11+
--
12+
--
13+
This test succeeds, but it gives a warning that the user has not provided a loop
14+
invariant. Hence, a default loop invariant (i.e. true) will be used.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
int main()
3+
{
4+
int i = 0;
5+
int N = 10;
6+
while(i != N)
7+
// clang-format off
8+
__CPROVER_loop_invariant(0 <= i && i <= N)
9+
__CPROVER_decreases(i)
10+
// clang-format on
11+
{
12+
i++;
13+
}
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+
--apply-loop-contracts
4+
^main.c function main$
5+
^\[main.1\] .* Check loop invariant before entry: SUCCESS$
6+
^\[main.2\] .* Check that loop invariant is preserved: SUCCESS$
7+
^\[main.3\] .* Check decreases clause on loop iteration: FAILURE$
8+
^.* 1 of 3 failed \(2 iterations\)$
9+
^VERIFICATION FAILED$
10+
^EXIT=10$
11+
^SIGNAL=0$
12+
--
13+
--
14+
This test fails because the decreases clause is not monotinically decreasing.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
CORE
22
main.c
3-
--enforce-all-contracts
3+
--apply-loop-contracts
44
activate-multi-line-match
55
^main.c.*error: syntax error before 'int'\n.*__CPROVER_decreases\(int x = 0\)$
66
^PARSING ERROR$
77
^EXIT=(1|64)$
88
^SIGNAL=0$
99
--
1010
--
11-
This test fails because the loop variant is a statement (more precisely,
11+
This test fails because the decreases clause is a statement (more precisely,
1212
an assignment) rather than an expression (more precisely, an ACSL binding
1313
expression).
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
CORE
22
main.c
3-
--enforce-all-contracts
3+
--apply-loop-contracts
44
activate-multi-line-match
55
^main.c.*error: syntax error before ','\n.*__CPROVER_decreases\(N - i, 42\)$
66
^PARSING ERROR$
77
^EXIT=(1|64)$
88
^SIGNAL=0$
99
--
1010
--
11-
This test fails because the loop variant has two arguments instead of just one.
12-
Currently, we only support loop variants of single arguments - we do not
13-
support loop variants of tuples (yet).
11+
This test fails because the decreases clause has two arguments instead of just one.
12+
Currently, we only support decreases clauses of single arguments - we do not
13+
support decreases clauses of tuples (yet).
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
int main()
2+
{
3+
int i = 0;
4+
int N = 10;
5+
while(i != N)
6+
// clang-format off
7+
__CPROVER_loop_invariant(0 <= i && i <= N)
8+
__CPROVER_decreases((N+=0) - i)
9+
// clang-format on
10+
{
11+
i++;
12+
}
13+
14+
return 0;
15+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
CORE
2+
main.c
3+
--apply-loop-contracts
4+
^Decreases clause is not side-effect free. \(at: file main.c line .* function main\)$
5+
^EXIT=70$
6+
^SIGNAL=0$
7+
--
8+
--
9+
This test fails because the decreases clause contains a side effect, namely
10+
incrementing variable N by zero. In this case, although the value of N
11+
remains unchanged after the increment operation, we read from and write to N.
12+
So this constitues a side effect. Decreases clauses are banned from containing
13+
side effects, since decreases clauses should not modify program states.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
int main()
3+
{
4+
int i = 0;
5+
int N = 10;
6+
while(i != N)
7+
// clang-format off
8+
__CPROVER_loop_invariant(i <= N)
9+
__CPROVER_decreases(N - i)
10+
// clang-format on
11+
{
12+
i++;
13+
}
14+
15+
return 0;
16+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
CORE
2+
main.c
3+
--apply-loop-contracts
4+
^main.c function main$
5+
^\[main.1\] .* Check loop invariant before entry: SUCCESS$
6+
^\[main.2\] .* Check that loop invariant is preserved: SUCCESS$
7+
^\[main.3\] .* Check decreases clause on loop iteration: FAILURE$
8+
^.* 1 of 3 failed \(2 iterations\)$
9+
^VERIFICATION FAILED$
10+
^EXIT=10$
11+
^SIGNAL=0$
12+
--
13+
--
14+
This test fails because the loop invariant is not strong enough for the
15+
termination proof. We must add 0 <= i to the loop invariant.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
2+
int main()
3+
{
4+
int i = 0;
5+
int N = 10;
6+
while(1 == 1)
7+
// clang-format off
8+
__CPROVER_loop_invariant(0 <= i && i <= N)
9+
__CPROVER_decreases(N - i)
10+
// clang-format on
11+
{
12+
if(i == 10)
13+
{
14+
break;
15+
}
16+
i++;
17+
}
18+
19+
return 0;
20+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
CORE
2+
main.c
3+
--apply-loop-contracts
4+
^main.c function main$
5+
^\[main.1\] .* Check loop invariant before entry: SUCCESS$
6+
^\[main.2\] .* Check that loop invariant is preserved: SUCCESS$
7+
^\[main.3\] .* Check decreases clause on loop iteration: SUCCESS$
8+
^.*0 of 3 failed \(1 iterations\)$
9+
^VERIFICATION SUCCESSFUL$
10+
^EXIT=0$
11+
^SIGNAL=0$
12+
--
13+
--
14+
This test succeeds. The purpose of this test is to check whether a decreases
15+
clause can successfully prove the termination of a loop (i) whose exit condition
16+
is 1 == 1 (i.e. true) and (ii) that will eventually exit via a break statement.

0 commit comments

Comments
 (0)