Description
CBMC version: 5.67.0
Operating system: N/A
Problem description
In the assigns
clause of loop-contracts and function-contracts, there are cases where we may need some kind of quantifiers to express the full set of assignable memory locations. An example of this is given below. Currently CBMC does not have any syntax to express such assigns clauses.
Ideally, we would like the solution to work in a fully-unbounded setting. Hence the number of constraints generated should be independent of the bounds of the quantified variable. But maybe this is too hard to achieve? A short-term solution can be to generate constraints that are proportional to the quantifier bounds.
Example
This example shows a simplified version of the assigns clause needed for a loop contract in the TaskIncrementTick function (in tasks.c) in the FreeRTOSKernel. It demonstrates a case where we need a quantifier in the assigns clause.
The FreeRTOSKernel code implemented with array-lists (the rewrite with array-lists avoids recursive data-structures like linked-lists for which we cannot write loop contracts in CBMC)can be found here:
https://github.com/akshayutture/FreeRTOS-Kernel/blob/arraylist_task_queue
#include<stdlib.h>
#define STATIC_MAX_CAPACITY 10
typedef struct{
int field;
} ListItem;
main(){
// Set the size
ListItem* listData[STATIC_MAX_CAPACITY];
size_t dynamic_list_size = nondet_uint();
__CPROVER_assume(dynamic_list_size < STATIC_MAX_CAPACITY);
// Allocate all the elements.
for (int i = 0 ; i <dynamic_list_size ; i++){
listData[i] = malloc(sizeof(ListItem));
}
// Missing syntax for the following assigns clause
for (int i = 0 ; i < dynamic_list_size ; i++)
/* new syntax used
__CPROVER_assigns (
forall i in (0,dynamic_list_size);
(0 < dynamic_list_size <= STATIC_MAX_CAPACITY);
__CPROVER_assignable(listData[i]->field)
)*/
{
listData[i]->field = 0;
}
}