@@ -55,6 +55,8 @@ class goto_check_ct
55
55
enable_bounds_check = _options.get_bool_option (" bounds-check" );
56
56
enable_pointer_check = _options.get_bool_option (" pointer-check" );
57
57
enable_memory_leak_check = _options.get_bool_option (" memory-leak-check" );
58
+ enable_memory_cleanup_check =
59
+ _options.get_bool_option (" memory-cleanup-check" );
58
60
enable_div_by_zero_check = _options.get_bool_option (" div-by-zero-check" );
59
61
enable_enum_range_check = _options.get_bool_option (" enum-range-check" );
60
62
enable_signed_overflow_check =
@@ -181,6 +183,7 @@ class goto_check_ct
181
183
void undefined_shift_check (const shift_exprt &, const guardt &);
182
184
void pointer_rel_check (const binary_exprt &, const guardt &);
183
185
void pointer_overflow_check (const exprt &, const guardt &);
186
+ void memory_leak_check (const irep_idt &function_id);
184
187
185
188
// / Generates VCCs for the validity of the given dereferencing operation.
186
189
// / \param expr the expression to be checked
@@ -256,6 +259,7 @@ class goto_check_ct
256
259
bool enable_bounds_check;
257
260
bool enable_pointer_check;
258
261
bool enable_memory_leak_check;
262
+ bool enable_memory_cleanup_check;
259
263
bool enable_div_by_zero_check;
260
264
bool enable_enum_range_check;
261
265
bool enable_signed_overflow_check;
@@ -275,6 +279,7 @@ class goto_check_ct
275
279
{" bounds-check" , &enable_bounds_check},
276
280
{" pointer-check" , &enable_pointer_check},
277
281
{" memory-leak-check" , &enable_memory_leak_check},
282
+ {" memory-cleanup-check" , &enable_memory_cleanup_check},
278
283
{" div-by-zero-check" , &enable_div_by_zero_check},
279
284
{" enum-range-check" , &enable_enum_range_check},
280
285
{" signed-overflow-check" , &enable_signed_overflow_check},
@@ -2045,6 +2050,28 @@ optionalt<exprt> goto_check_ct::expand_pointer_checks(exprt expr)
2045
2050
return {};
2046
2051
}
2047
2052
2053
+ void goto_check_ct::memory_leak_check (const irep_idt &function_id)
2054
+ {
2055
+ const symbolt &leak = ns.lookup (CPROVER_PREFIX " memory_leak" );
2056
+ const symbol_exprt leak_expr = leak.symbol_expr ();
2057
+
2058
+ // add self-assignment to get helpful counterexample output
2059
+ new_code.add (goto_programt::make_assignment (leak_expr, leak_expr));
2060
+
2061
+ source_locationt source_location;
2062
+ source_location.set_function (function_id);
2063
+
2064
+ equal_exprt eq (leak_expr, null_pointer_exprt (to_pointer_type (leak.type )));
2065
+
2066
+ add_guarded_property (
2067
+ eq,
2068
+ " dynamically allocated memory never freed" ,
2069
+ " memory-leak" ,
2070
+ source_location,
2071
+ eq,
2072
+ identity);
2073
+ }
2074
+
2048
2075
void goto_check_ct::goto_check (
2049
2076
const irep_idt &function_identifier,
2050
2077
goto_functiont &goto_function)
@@ -2196,6 +2223,19 @@ void goto_check_ct::goto_check(
2196
2223
// this has no successor
2197
2224
assertions.clear ();
2198
2225
}
2226
+ else if (i.is_assume ())
2227
+ {
2228
+ // These are further 'exit points' of the program
2229
+ const exprt simplified_guard = simplify_expr (i.condition (), ns);
2230
+ if (
2231
+ enable_memory_cleanup_check && simplified_guard.is_false () &&
2232
+ (function_identifier == " abort" || function_identifier == " exit" ||
2233
+ function_identifier == " _Exit" ||
2234
+ (i.labels .size () == 1 && i.labels .front () == " __VERIFIER_abort" )))
2235
+ {
2236
+ memory_leak_check (function_identifier);
2237
+ }
2238
+ }
2199
2239
else if (i.is_dead ())
2200
2240
{
2201
2241
if (enable_pointer_check || enable_pointer_primitive_check)
@@ -2225,24 +2265,7 @@ void goto_check_ct::goto_check(
2225
2265
function_identifier == goto_functionst::entry_point () &&
2226
2266
enable_memory_leak_check)
2227
2267
{
2228
- const symbolt &leak = ns.lookup (CPROVER_PREFIX " memory_leak" );
2229
- const symbol_exprt leak_expr = leak.symbol_expr ();
2230
-
2231
- // add self-assignment to get helpful counterexample output
2232
- new_code.add (goto_programt::make_assignment (leak_expr, leak_expr));
2233
-
2234
- source_locationt source_location;
2235
- source_location.set_function (function_identifier);
2236
-
2237
- equal_exprt eq (
2238
- leak_expr, null_pointer_exprt (to_pointer_type (leak.type )));
2239
- add_guarded_property (
2240
- eq,
2241
- " dynamically allocated memory never freed" ,
2242
- " memory-leak" ,
2243
- source_location,
2244
- eq,
2245
- identity);
2268
+ memory_leak_check (function_identifier);
2246
2269
}
2247
2270
}
2248
2271
0 commit comments