|
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