@@ -112,50 +112,55 @@ __CPROVER_bool __VERIFIER_nondet___CPROVER_bool();
112112
113113inline void * malloc (__CPROVER_size_t malloc_size )
114114{
115- // realistically, malloc may return NULL,
116- // and __CPROVER_allocate doesn't, but no one cares
117- __CPROVER_HIDE :;
115+ // realistically, malloc may return NULL,
116+ // but we only do so if `--malloc-may-fail` is set
117+ __CPROVER_HIDE :;
118118
119+ if (__CPROVER_malloc_failure_mode == __CPROVER_malloc_failure_mode_return_null )
120+ {
121+ __CPROVER_bool should_malloc_fail = __VERIFIER_nondet___CPROVER_bool ();
119122 if (
120- __CPROVER_malloc_failure_mode ==
121- __CPROVER_malloc_failure_mode_return_null )
122- {
123- if (malloc_size > __CPROVER_max_malloc_size )
124- {
125- return (void * )0 ;
126- }
127- }
128- else if (
129- __CPROVER_malloc_failure_mode ==
130- __CPROVER_malloc_failure_mode_assert_then_assume )
123+ malloc_size > __CPROVER_max_malloc_size ||
124+ (__CPROVER_malloc_may_fail && should_malloc_fail ))
131125 {
132- __CPROVER_assert (
133- malloc_size <= __CPROVER_max_malloc_size ,
134- "max allocation size exceeded" );
135- __CPROVER_assume (malloc_size <= __CPROVER_max_malloc_size );
126+ return (void * )0 ;
136127 }
128+ }
129+ else if (
130+ __CPROVER_malloc_failure_mode ==
131+ __CPROVER_malloc_failure_mode_assert_then_assume )
132+ {
133+ __CPROVER_assert (
134+ malloc_size <= __CPROVER_max_malloc_size , "max allocation size exceeded" );
135+ __CPROVER_assume (malloc_size <= __CPROVER_max_malloc_size );
136+
137+ __CPROVER_bool should_malloc_fail = __VERIFIER_nondet___CPROVER_bool ();
138+ __CPROVER_assert (
139+ !__CPROVER_malloc_may_fail || !should_malloc_fail ,
140+ "max allocation may fail" );
141+ __CPROVER_assume (!__CPROVER_malloc_may_fail || !should_malloc_fail );
142+ }
137143
138- void * malloc_res ;
139- malloc_res = __CPROVER_allocate (malloc_size , 0 );
144+ void * malloc_res ;
145+ malloc_res = __CPROVER_allocate (malloc_size , 0 );
140146
141- // make sure it's not recorded as deallocated
142- __CPROVER_deallocated =
143- (malloc_res == __CPROVER_deallocated ) ? 0 : __CPROVER_deallocated ;
147+ // make sure it's not recorded as deallocated
148+ __CPROVER_deallocated =
149+ (malloc_res == __CPROVER_deallocated ) ? 0 : __CPROVER_deallocated ;
144150
145- // record the object size for non-determistic bounds checking
146- __CPROVER_bool record_malloc = __VERIFIER_nondet___CPROVER_bool ();
147- __CPROVER_malloc_object =
148- record_malloc ? malloc_res : __CPROVER_malloc_object ;
149- __CPROVER_malloc_size = record_malloc ? malloc_size : __CPROVER_malloc_size ;
150- __CPROVER_malloc_is_new_array =
151- record_malloc ? 0 : __CPROVER_malloc_is_new_array ;
151+ // record the object size for non-determistic bounds checking
152+ __CPROVER_bool record_malloc = __VERIFIER_nondet___CPROVER_bool ();
153+ __CPROVER_malloc_object =
154+ record_malloc ? malloc_res : __CPROVER_malloc_object ;
155+ __CPROVER_malloc_size = record_malloc ? malloc_size : __CPROVER_malloc_size ;
156+ __CPROVER_malloc_is_new_array =
157+ record_malloc ? 0 : __CPROVER_malloc_is_new_array ;
152158
153- // detect memory leaks
154- __CPROVER_bool record_may_leak = __VERIFIER_nondet___CPROVER_bool ();
155- __CPROVER_memory_leak =
156- record_may_leak ? malloc_res : __CPROVER_memory_leak ;
159+ // detect memory leaks
160+ __CPROVER_bool record_may_leak = __VERIFIER_nondet___CPROVER_bool ();
161+ __CPROVER_memory_leak = record_may_leak ? malloc_res : __CPROVER_memory_leak ;
157162
158- return malloc_res ;
163+ return malloc_res ;
159164}
160165
161166/* FUNCTION: __builtin_alloca */
@@ -446,7 +451,8 @@ inline void *realloc(void *ptr, __CPROVER_size_t malloc_size)
446451 // this shouldn't move if the new size isn't bigger
447452 void * res ;
448453 res = malloc (malloc_size );
449- __CPROVER_array_copy (res , ptr );
454+ if (res != (void * )0 )
455+ __CPROVER_array_copy (res , ptr );
450456 free (ptr );
451457
452458 return res ;
0 commit comments