Skip to content

Commit c94548c

Browse files
author
Daniel Kroening
committed
preconditions for delete and delete[]
1 parent 2bb98d9 commit c94548c

File tree

1 file changed

+33
-28
lines changed

1 file changed

+33
-28
lines changed

src/ansi-c/library/new.c

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -72,30 +72,32 @@ __CPROVER_bool __VERIFIER_nondet___CPROVER_bool();
7272
inline void __delete(void *ptr)
7373
{
7474
__CPROVER_HIDE:;
75+
// is it dynamic?
76+
__CPROVER_precondition(ptr==0 || __CPROVER_DYNAMIC_OBJECT(ptr),
77+
"delete argument must be dynamic object");
78+
__CPROVER_precondition(__CPROVER_POINTER_OFFSET(ptr)==0,
79+
"delete argument must have offset zero");
80+
81+
// catch double delete
82+
__CPROVER_precondition(ptr==0 || __CPROVER_deallocated!=ptr, "double delete");
83+
84+
// catch people who call delete for objects allocated with new[]
85+
__CPROVER_precondition(ptr==0 ||
86+
__CPROVER_malloc_object!=ptr ||
87+
!__CPROVER_malloc_is_new_array,
88+
"delete of array object");
89+
7590
// If ptr is NULL, no operation is performed.
7691
// This is a requirement by the standard, not generosity!
7792
if(ptr!=0)
7893
{
79-
// is it dynamic?
80-
__CPROVER_assert(__CPROVER_DYNAMIC_OBJECT(ptr),
81-
"delete argument must be dynamic object");
82-
__CPROVER_assert(__CPROVER_POINTER_OFFSET(ptr)==0,
83-
"delete argument must have offset zero");
84-
85-
// catch double delete
86-
__CPROVER_assert(__CPROVER_deallocated!=ptr, "double delete");
87-
88-
// catch people who call delete for objects allocated with new[]
89-
__CPROVER_assert(__CPROVER_malloc_object!=ptr ||
90-
!__CPROVER_malloc_is_new_array,
91-
"delete of array object");
92-
9394
// non-deterministically record as deallocated
9495
__CPROVER_bool record=__VERIFIER_nondet___CPROVER_bool();
9596
__CPROVER_deallocated=record?ptr:__CPROVER_deallocated;
9697

9798
// detect memory leaks
98-
if(__CPROVER_memory_leak==ptr) __CPROVER_memory_leak=0;
99+
if(__CPROVER_memory_leak==ptr)
100+
__CPROVER_memory_leak=0;
99101
}
100102
}
101103

@@ -108,22 +110,25 @@ inline void __delete_array(void *ptr)
108110
__CPROVER_HIDE:;
109111
// If ptr is NULL, no operation is performed.
110112
// This is a requirement by the standard, not generosity!
111-
if(ptr!=0)
112-
{
113-
// is it dynamic?
114-
__CPROVER_assert(__CPROVER_DYNAMIC_OBJECT(ptr),
115-
"delete argument must be dynamic object");
116-
__CPROVER_assert(__CPROVER_POINTER_OFFSET(ptr)==0,
117-
"delete argument must have offset zero");
118113

119-
// catch double delete
120-
__CPROVER_assert(__CPROVER_deallocated!=ptr, "double delete");
114+
// is it dynamic?
115+
__CPROVER_precondition(ptr==0 || __CPROVER_DYNAMIC_OBJECT(ptr),
116+
"delete argument must be dynamic object");
117+
__CPROVER_precondition(ptr==0 || __CPROVER_POINTER_OFFSET(ptr)==0,
118+
"delete argument must have offset zero");
121119

122-
// catch people who call delete[] for objects allocated with new
123-
__CPROVER_assert(__CPROVER_malloc_object!=ptr ||
124-
__CPROVER_malloc_is_new_array,
125-
"delete[] of non-array object");
120+
// catch double delete
121+
__CPROVER_precondition(ptr==0 || __CPROVER_deallocated!=ptr,
122+
"double delete");
126123

124+
// catch people who call delete[] for objects allocated with new
125+
__CPROVER_precondition(ptr==0 ||
126+
__CPROVER_malloc_object!=ptr ||
127+
__CPROVER_malloc_is_new_array,
128+
"delete[] of non-array object");
129+
130+
if(ptr!=0)
131+
{
127132
// non-deterministically record as deallocated
128133
__CPROVER_bool record=__VERIFIER_nondet___CPROVER_bool();
129134
__CPROVER_deallocated=record?ptr:__CPROVER_deallocated;

0 commit comments

Comments
 (0)