Skip to content

Commit f37240f

Browse files
committed
binary_seaech regression test for loop contracts
1 parent f0ab57e commit f37240f

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#include <assert.h>
2+
#include <stdbool.h>
3+
#include <stdlib.h>
4+
5+
#define NOT_FOUND (-1)
6+
7+
int binary_search(int val, int *buf, int size)
8+
{
9+
if(size <= 0 || buf == NULL)
10+
return NOT_FOUND;
11+
12+
long long lb = 0, ub = size - 1;
13+
long long mid = (lb + ub) / 2;
14+
15+
while(lb <= ub)
16+
// clang-format off
17+
__CPROVER_loop_invariant(0L <= lb && lb - 1L <= ub && ub < size)
18+
__CPROVER_loop_invariant(mid == (lb + ub) / 2L)
19+
__CPROVER_decreases(ub - lb)
20+
// clang-format on
21+
{
22+
if(buf[mid] == val)
23+
break;
24+
if(buf[mid] < val)
25+
lb = mid + 1;
26+
else
27+
ub = mid - 1;
28+
mid = (lb + ub) / 2;
29+
}
30+
return lb > ub ? NOT_FOUND : mid;
31+
}
32+
33+
int main()
34+
{
35+
int val, size;
36+
int *buf = size >= 0 ? malloc(size * sizeof(int)) : NULL;
37+
38+
int idx = binary_search(val, buf, size);
39+
if(idx != NOT_FOUND)
40+
assert(buf[idx] == val);
41+
}
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 _ --pointer-check --bounds-check --signed-overflow-check
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^\[binary_search.1\] .* Check loop invariant before entry: SUCCESS$
7+
^\[binary_search.2\] .* Check that loop invariant is preserved: SUCCESS$
8+
^\[binary_search.3\] .* Check decreases clause on loop iteration: SUCCESS$
9+
^\[main.assertion.1\] .* assertion buf\[idx\] == val: SUCCESS$
10+
^VERIFICATION SUCCESSFUL$
11+
--
12+
--
13+
This test case verifies memory safety and termination of a binary search implementation.

0 commit comments

Comments
 (0)