@@ -75,6 +75,31 @@ __CPROVER_HIDE:;
75
75
__CPROVER_size_t alloc_size = nmemb * size ;
76
76
#pragma CPROVER check pop
77
77
78
+ if (__CPROVER_malloc_failure_mode == __CPROVER_malloc_failure_mode_return_null )
79
+ {
80
+ __CPROVER_bool should_malloc_fail = __VERIFIER_nondet___CPROVER_bool ();
81
+ if (
82
+ alloc_size > __CPROVER_max_malloc_size ||
83
+ (__CPROVER_malloc_may_fail && should_malloc_fail ))
84
+ {
85
+ return (void * )0 ;
86
+ }
87
+ }
88
+ else if (
89
+ __CPROVER_malloc_failure_mode ==
90
+ __CPROVER_malloc_failure_mode_assert_then_assume )
91
+ {
92
+ __CPROVER_assert (
93
+ alloc_size <= __CPROVER_max_malloc_size , "max allocation size exceeded" );
94
+ __CPROVER_assume (alloc_size <= __CPROVER_max_malloc_size );
95
+
96
+ __CPROVER_bool should_malloc_fail = __VERIFIER_nondet___CPROVER_bool ();
97
+ __CPROVER_assert (
98
+ !__CPROVER_malloc_may_fail || !should_malloc_fail ,
99
+ "max allocation may fail" );
100
+ __CPROVER_assume (!__CPROVER_malloc_may_fail || !should_malloc_fail );
101
+ }
102
+
78
103
void * malloc_res ;
79
104
// realistically, calloc may return NULL,
80
105
// and __CPROVER_allocate doesn't, but no one cares
@@ -112,50 +137,55 @@ __CPROVER_bool __VERIFIER_nondet___CPROVER_bool();
112
137
113
138
inline void * malloc (__CPROVER_size_t malloc_size )
114
139
{
115
- // realistically, malloc may return NULL,
116
- // and __CPROVER_allocate doesn't, but no one cares
117
- __CPROVER_HIDE :;
140
+ // realistically, malloc may return NULL,
141
+ // but we only do so if `--malloc-may-fail` is set
142
+ __CPROVER_HIDE :;
118
143
144
+ if (__CPROVER_malloc_failure_mode == __CPROVER_malloc_failure_mode_return_null )
145
+ {
146
+ __CPROVER_bool should_malloc_fail = __VERIFIER_nondet___CPROVER_bool ();
119
147
if (
120
- __CPROVER_malloc_failure_mode ==
121
- __CPROVER_malloc_failure_mode_return_null )
148
+ malloc_size > __CPROVER_max_malloc_size ||
149
+ ( __CPROVER_malloc_may_fail && should_malloc_fail ) )
122
150
{
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 )
131
- {
132
- __CPROVER_assert (
133
- malloc_size <= __CPROVER_max_malloc_size ,
134
- "max allocation size exceeded" );
135
- __CPROVER_assume (malloc_size <= __CPROVER_max_malloc_size );
151
+ return (void * )0 ;
136
152
}
153
+ }
154
+ else if (
155
+ __CPROVER_malloc_failure_mode ==
156
+ __CPROVER_malloc_failure_mode_assert_then_assume )
157
+ {
158
+ __CPROVER_assert (
159
+ malloc_size <= __CPROVER_max_malloc_size , "max allocation size exceeded" );
160
+ __CPROVER_assume (malloc_size <= __CPROVER_max_malloc_size );
161
+
162
+ __CPROVER_bool should_malloc_fail = __VERIFIER_nondet___CPROVER_bool ();
163
+ __CPROVER_assert (
164
+ !__CPROVER_malloc_may_fail || !should_malloc_fail ,
165
+ "max allocation may fail" );
166
+ __CPROVER_assume (!__CPROVER_malloc_may_fail || !should_malloc_fail );
167
+ }
137
168
138
- void * malloc_res ;
139
- malloc_res = __CPROVER_allocate (malloc_size , 0 );
169
+ void * malloc_res ;
170
+ malloc_res = __CPROVER_allocate (malloc_size , 0 );
140
171
141
- // make sure it's not recorded as deallocated
142
- __CPROVER_deallocated =
143
- (malloc_res == __CPROVER_deallocated ) ? 0 : __CPROVER_deallocated ;
172
+ // make sure it's not recorded as deallocated
173
+ __CPROVER_deallocated =
174
+ (malloc_res == __CPROVER_deallocated ) ? 0 : __CPROVER_deallocated ;
144
175
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 ;
176
+ // record the object size for non-determistic bounds checking
177
+ __CPROVER_bool record_malloc = __VERIFIER_nondet___CPROVER_bool ();
178
+ __CPROVER_malloc_object =
179
+ record_malloc ? malloc_res : __CPROVER_malloc_object ;
180
+ __CPROVER_malloc_size = record_malloc ? malloc_size : __CPROVER_malloc_size ;
181
+ __CPROVER_malloc_is_new_array =
182
+ record_malloc ? 0 : __CPROVER_malloc_is_new_array ;
152
183
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 ;
184
+ // detect memory leaks
185
+ __CPROVER_bool record_may_leak = __VERIFIER_nondet___CPROVER_bool ();
186
+ __CPROVER_memory_leak = record_may_leak ? malloc_res : __CPROVER_memory_leak ;
157
187
158
- return malloc_res ;
188
+ return malloc_res ;
159
189
}
160
190
161
191
/* FUNCTION: __builtin_alloca */
@@ -446,7 +476,8 @@ inline void *realloc(void *ptr, __CPROVER_size_t malloc_size)
446
476
// this shouldn't move if the new size isn't bigger
447
477
void * res ;
448
478
res = malloc (malloc_size );
449
- __CPROVER_array_copy (res , ptr );
479
+ if (res != (void * )0 )
480
+ __CPROVER_array_copy (res , ptr );
450
481
free (ptr );
451
482
452
483
return res ;
0 commit comments