CBMC
Write Set Representation

Back to Dynamic Frame Condition Checking

Write Set Data Structure

The write set type and its basic operations are implemented in the file cprover_contracts.c.

Assignable ranges of bytes specified in assigns clauses are represented by the __CPROVER_contracts_car_t :

// A conditionally writable range of bytes.
{
// True iff __CPROVER_w_ok(lb, size) holds at creation
__CPROVER_bool is_writable;
//Size of the range in bytes
__CPROVER_size_t size;
//Lower bound address of the range
void *lb;
//Upper bound address of the range
void *ub;
A conditionally writable range of bytes.
__CPROVER_size_t size
Size of the range in bytes.
void * lb
Lower bound address of the range.
void * ub
Upper bound address of the range.
unsigned char is_writable
True iff __CPROVER_w_ok(lb, size) holds at creation.

Sets of __CPROVER_contracts_car_t are represented as dynamic arrays __CPROVER_contracts_car_set_t, allocated by the __CPROVER_contracts_car_set_create function.

{
__CPROVER_size_t max_elems;
A set of __CPROVER_contracts_car_t.
__CPROVER_size_t max_elems
Maximum number of elements that can be stored in the set.
__CPROVER_contracts_car_t * elems
An array of car_t of size max_elems.

The allocated size of a set is determined by the maximum number of targets found in the assigns clause of the contract of interest.

Objects for which all bytes are assignable (or freeable) do not need to be represented as __CPROVER_contracts_car_t. They can be tracked using a single pointer or object identifier.

Such sets of pointers are represented by the __CPROVER_contracts_obj_set_t data type.

// A set of pointers.
{
// Maximum number of elements that can be stored in the set
__CPROVER_size_t max_elems;
// next usable index in elems if less than max_elems
__CPROVER_size_t watermark;
// Number of elements currently in the elems array
__CPROVER_size_t nof_elems;
// True iff nof_elems is 0
__CPROVER_bool is_empty;
// True iff elems is indexed by the object id of the pointers
__CPROVER_bool indexed_by_object_id;
// Array of void *pointers, indexed by their object ID or some arbitrary order
void **elems;
void ** elems
Array of void *pointers, indexed by their object ID or some other order.
unsigned char is_empty
True iff nof_elems is 0.
__CPROVER_size_t watermark
next usable index in elems if less than max_elems (1 + greatest used index in elems)
unsigned char indexed_by_object_id
True iff elems is indexed by the object id of the pointers.
__CPROVER_size_t nof_elems
Number of elements currently in the elems array.
__CPROVER_size_t max_elems
Maximum number of elements that can be stored in the set.

The void **elem array can be used in two distinct modes, controlled by the field indexed_by_object_id:

  1. When indexed_by_object_id is true, the container works in indexed mode. The elems array is allocated to a size 2^OBJECT_BITS, and adding a pointer p to the set stores it at elems[__CPROVER_POINTER_OBJECT(p)]. This mode allows for efficient insertions and lookups but results in a sparse array;
  2. When indexed_by_object_id is false, the container works in append mode. elems is allocated to a manually specified size, and adding pointer p stores it at elems[watermark] and increments watermark by one. This mode densely packs all pointers at the beginning of the array and allows for iteration over the stored pointers.

Last, actual write sets are represented by the type __CPROVER_contracts_write_set_t :

// Runtime representation of a write set.
{
// Set of car derived from the contract
// Set of freeable pointers derived from the contract (indexed mode)
// Set of freeable pointers derived from the contract (append mode)
__CPROVER_contracts_obj_set_t contract_frees_replacement;
// Set of objects allocated by the function under analysis (indexed mode)
// Set of objects deallocated by the function under analysis (indexed mode)
// Object set supporting the is_fresh predicate checks (indexed mode)
// Object set recording the is_fresh allocations in post conditions
// (replacement mode only)
// Object set recording the deallocations (used by predicate was_freed)
// True iff this write set is used for contract replacement
__CPROVER_bool replacement;
// True iff the write set checks requires clauses in an assumption ctx
__CPROVER_bool assume_requires_ctx;
// True iff the write set checks requires clauses in an assertion ctx
__CPROVER_bool assert_requires_ctx;
// True iff the write set checks ensures clauses in an assumption ctx
__CPROVER_bool assume_ensures_ctx;
// True iff this write set checks ensures clauses in an assertion ctx
__CPROVER_bool assert_ensures_ctx;
Runtime representation of a write set.
__CPROVER_contracts_obj_set_ptr_t linked_allocated
Object set recording the is_fresh allocations in post conditions.
unsigned char assume_ensures_ctx
True iff the write set checks ensures clauses in an assumption ctx.
__CPROVER_contracts_obj_set_t contract_frees
Set of freeable pointers derived from the contract (indexed mode)
__CPROVER_contracts_obj_set_t deallocated
Set of objects deallocated by the function under analysis (indexed mode)
unsigned char assume_requires_ctx
True iff the write set checks requires clauses in an assumption ctx.
__CPROVER_contracts_obj_set_ptr_t linked_deallocated
Object set recording the deallocations (used by was_freed)
__CPROVER_contracts_obj_set_ptr_t linked_is_fresh
Pointer to object set supporting the is_fresh predicate checks (indexed mode)
__CPROVER_contracts_car_set_t contract_assigns
Set of car derived from the contract.
unsigned char assert_ensures_ctx
True iff this write set checks ensures clauses in an assertion ctx.
unsigned char assert_requires_ctx
True iff the write set checks requires clauses in an assertion ctx.
__CPROVER_contracts_obj_set_t allocated
Set of objects allocated by the function under analysis (indexed mode)

Write Set Operations

Direct links to __CPROVER_contracts_write_set_t operations documentation (full documentation available at cprover_contracts.c) :


Prev Next
Dynamic Frame Condition Checking GOTO Function Instrumentation