|
1 | 1 | #include <stdbool.h>
|
2 | 2 | #include <stdlib.h>
|
3 | 3 |
|
4 |
| -typedef struct list_t |
5 |
| -{ |
6 |
| - int value; |
7 |
| - struct list_t *next; |
8 |
| -} list_t; |
9 |
| - |
10 |
| -#define MIN_VALUE -10 |
11 |
| -#define MAX_VALUE 10 |
12 |
| - |
13 |
| -bool is_list(list_t *l, size_t len) |
14 |
| -{ |
15 |
| - if(len == 0) |
16 |
| - return l == NULL; |
17 |
| - else |
18 |
| - return __CPROVER_is_fresh(l, sizeof(*l)) && |
19 |
| - (MIN_VALUE <= l->value && l->value <= MAX_VALUE) && |
20 |
| - is_list(l->next, len - 1); |
21 |
| -} |
| 4 | +#define BUFFER_SIZE 10 |
22 | 5 |
|
23 | 6 | typedef struct buffer_t
|
24 | 7 | {
|
25 | 8 | size_t size;
|
26 | 9 | char *arr;
|
27 | 10 | } buffer_t;
|
28 | 11 |
|
29 |
| -typedef struct double_buffer_t |
30 |
| -{ |
31 |
| - buffer_t *first; |
32 |
| - buffer_t *second; |
33 |
| -} double_buffer_t; |
34 |
| - |
35 |
| -#define MIN_BUFFER_SIZE 1 |
36 |
| -#define MAX_BUFFER_SIZE 10 |
37 |
| - |
| 12 | +// predicat describing an array of size BUFFER_SIZE |
38 | 13 | bool is_sized_array(char *arr, size_t size)
|
39 | 14 | {
|
40 |
| - return (MIN_BUFFER_SIZE <= size && size <= MAX_BUFFER_SIZE) && |
41 |
| - __CPROVER_is_fresh(arr, size); |
42 |
| -} |
43 |
| - |
44 |
| -bool is_buffer(buffer_t *b) |
45 |
| -{ |
46 |
| - return __CPROVER_is_fresh(b, sizeof(*b)) && is_sized_array(b->arr, b->size); |
47 |
| -} |
48 |
| - |
49 |
| -bool is_double_buffer(double_buffer_t *b) |
50 |
| -{ |
51 |
| - return __CPROVER_is_fresh(b, sizeof(*b)) && is_buffer(b->first) && |
52 |
| - is_buffer(b->second); |
| 15 | + return (size == 0 && arr == NULL) || |
| 16 | + (size == BUFFER_SIZE) && __CPROVER_is_fresh(arr, size); |
53 | 17 | }
|
54 | 18 |
|
55 |
| -#define LIST_LEN 3 |
56 |
| - |
57 |
| -list_t *create_node(int value, list_t *next) |
58 |
| -{ |
59 |
| - assert(MIN_VALUE <= value && value <= MAX_VALUE); |
60 |
| - list_t *result = malloc(sizeof(list_t)); |
61 |
| - result->value = value; |
62 |
| - result->next = next; |
63 |
| - return result; |
64 |
| -} |
65 |
| - |
66 |
| -buffer_t *create_buffer(size_t size) |
67 |
| -{ |
68 |
| - assert(MIN_BUFFER_SIZE <= size && size <= MAX_BUFFER_SIZE); |
69 |
| - buffer_t *result = malloc(sizeof(buffer_t)); |
70 |
| - result->arr = malloc(size); |
71 |
| - result->size = size; |
72 |
| - return result; |
73 |
| -} |
74 |
| - |
75 |
| -double_buffer_t *create_double_buffer(size_t first_size, size_t second_size) |
76 |
| -{ |
77 |
| - double_buffer_t *result = malloc(sizeof(double_buffer_t)); |
78 |
| - result->first = create_buffer(first_size); |
79 |
| - result->second = create_buffer(second_size); |
80 |
| - return result; |
81 |
| -} |
82 |
| - |
83 |
| -void foo(list_t **l, double_buffer_t **b) |
| 19 | +// takes pointers to pointers to list and double buffer and initialises them |
| 20 | +// by building a list of length 3 and a double buffer. |
| 21 | +void foo(buffer_t *b) |
84 | 22 | // clang-format off
|
85 |
| -__CPROVER_requires(__CPROVER_is_fresh(l, sizeof(*l))) |
86 | 23 | __CPROVER_requires(__CPROVER_is_fresh(b, sizeof(*b)))
|
87 |
| -__CPROVER_assigns(*l, *b) __CPROVER_ensures(is_list(*l, LIST_LEN)) |
88 |
| -__CPROVER_ensures(is_double_buffer(*b)) |
| 24 | +__CPROVER_assigns(*b) |
| 25 | +__CPROVER_ensures(is_sized_array(b->arr, b->size)) |
89 | 26 | // clang-format on
|
90 | 27 | {
|
91 |
| - *l = create_node(1, create_node(2, create_node(3, NULL))); |
92 |
| - *b = create_double_buffer(1, 10); |
| 28 | + b->arr = malloc(BUFFER_SIZE); |
| 29 | + if(b->arr == NULL) |
| 30 | + { |
| 31 | + b->size = 0; |
| 32 | + } |
| 33 | + else |
| 34 | + { |
| 35 | + b->size = BUFFER_SIZE; |
| 36 | + } |
93 | 37 | }
|
94 | 38 |
|
95 | 39 | void bar()
|
96 | 40 | {
|
97 |
| - list_t *l = NULL; |
98 |
| - double_buffer_t *b = NULL; |
99 |
| - |
100 |
| - foo(&l, &b); |
101 |
| - |
102 |
| - assert(__CPROVER_r_ok(l, sizeof(list_t))); |
103 |
| - assert(__CPROVER_r_ok(l->next, sizeof(list_t))); |
104 |
| - assert(__CPROVER_r_ok(l->next->next, sizeof(list_t))); |
105 |
| - assert(l->next->next->next == NULL); |
106 |
| - assert(MIN_VALUE <= l->value && l->value <= MAX_VALUE); |
107 |
| - assert(MIN_VALUE <= l->next->value && l->next->value <= MAX_VALUE); |
108 |
| - assert( |
109 |
| - MIN_VALUE <= l->next->next->value && l->next->next->value <= MAX_VALUE); |
110 |
| - assert(__CPROVER_r_ok(b, sizeof(double_buffer_t))); |
111 |
| - assert(__CPROVER_r_ok(b->first, sizeof(buffer_t))); |
112 |
| - assert(__CPROVER_r_ok(b->first->arr, b->first->size)); |
113 |
| - assert( |
114 |
| - MIN_BUFFER_SIZE <= b->first->size && b->first->size <= MAX_BUFFER_SIZE); |
115 |
| - assert(__CPROVER_r_ok(b->second, sizeof(buffer_t))); |
116 |
| - assert(__CPROVER_r_ok(b->second->arr, b->second->size)); |
117 |
| - assert( |
118 |
| - MIN_BUFFER_SIZE <= b->second->size && b->second->size <= MAX_BUFFER_SIZE); |
| 41 | + buffer_t b; |
| 42 | + foo(&b); |
| 43 | + // check presence of buffer object |
| 44 | + if(b.size == 0) |
| 45 | + { |
| 46 | + assert(b.arr == NULL); |
| 47 | + } |
| 48 | + else |
| 49 | + { |
| 50 | + assert(b.size == BUFFER_SIZE); |
| 51 | + assert(__CPROVER_r_ok(b.arr, b.size)); |
| 52 | + } |
119 | 53 | }
|
120 | 54 |
|
121 | 55 | int main()
|
|
0 commit comments