inline void __delete(void *ptr) { __CPROVER_HIDE:; // If ptr is NULL, no operation is performed. // This is a requirement by the standard, not generosity! if(ptr!=0) { // is it dynamic? __CPROVER_assert(__CPROVER_DYNAMIC_OBJECT(ptr), "delete argument must be dynamic object"); __CPROVER_assert(__CPROVER_POINTER_OFFSET(ptr)==0, "delete argument must have offset zero"); // catch double delete __CPROVER_assert(__CPROVER_deallocated!=ptr, "double delete"); // catch people who call delete for objects allocated with new[] __CPROVER_assert(__CPROVER_malloc_object!=ptr || !__CPROVER_malloc_is_new_array, "delete of array object"); // non-deterministically record as deallocated __CPROVER_bool record=__VERIFIER_nondet___CPROVER_bool(); __CPROVER_deallocated=record?ptr:__CPROVER_deallocated; // detect memory leaks if(__CPROVER_memory_leak==ptr) __CPROVER_memory_leak=0; } }
inline void free(void *ptr) { __CPROVER_HIDE:; // If ptr is NULL, no operation is performed. if(ptr!=0) { // is it dynamic? __CPROVER_assert(__CPROVER_DYNAMIC_OBJECT(ptr), "free argument is dynamic object"); __CPROVER_assert(__CPROVER_POINTER_OFFSET(ptr)==0, "free argument has offset zero"); // catch double free if(__CPROVER_deallocated==ptr) __CPROVER_assert(0, "double free"); // catch people who try to use free(...) for stuff // allocated with new[] __CPROVER_assert(__CPROVER_malloc_object!=ptr || !__CPROVER_malloc_is_new_array, "free called for new[] object"); // non-deterministically record as deallocated _Bool record; if(record) __CPROVER_deallocated=ptr; } }