@@ -55,6 +55,8 @@ class goto_check_ct
5555 enable_bounds_check = _options.get_bool_option (" bounds-check" );
5656 enable_pointer_check = _options.get_bool_option (" pointer-check" );
5757 enable_memory_leak_check = _options.get_bool_option (" memory-leak-check" );
58+ enable_memory_cleanup_check =
59+ _options.get_bool_option (" memory-cleanup-check" );
5860 enable_div_by_zero_check = _options.get_bool_option (" div-by-zero-check" );
5961 enable_enum_range_check = _options.get_bool_option (" enum-range-check" );
6062 enable_signed_overflow_check =
@@ -181,6 +183,7 @@ class goto_check_ct
181183 void undefined_shift_check (const shift_exprt &, const guardt &);
182184 void pointer_rel_check (const binary_exprt &, const guardt &);
183185 void pointer_overflow_check (const exprt &, const guardt &);
186+ void memory_leak_check (const irep_idt &function_id);
184187
185188 // / Generates VCCs for the validity of the given dereferencing operation.
186189 // / \param expr the expression to be checked
@@ -256,6 +259,7 @@ class goto_check_ct
256259 bool enable_bounds_check;
257260 bool enable_pointer_check;
258261 bool enable_memory_leak_check;
262+ bool enable_memory_cleanup_check;
259263 bool enable_div_by_zero_check;
260264 bool enable_enum_range_check;
261265 bool enable_signed_overflow_check;
@@ -275,6 +279,7 @@ class goto_check_ct
275279 {" bounds-check" , &enable_bounds_check},
276280 {" pointer-check" , &enable_pointer_check},
277281 {" memory-leak-check" , &enable_memory_leak_check},
282+ {" memory-cleanup-check" , &enable_memory_cleanup_check},
278283 {" div-by-zero-check" , &enable_div_by_zero_check},
279284 {" enum-range-check" , &enable_enum_range_check},
280285 {" signed-overflow-check" , &enable_signed_overflow_check},
@@ -2045,6 +2050,28 @@ optionalt<exprt> goto_check_ct::expand_pointer_checks(exprt expr)
20452050 return {};
20462051}
20472052
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+
20482075void goto_check_ct::goto_check (
20492076 const irep_idt &function_identifier,
20502077 goto_functiont &goto_function)
@@ -2196,6 +2223,19 @@ void goto_check_ct::goto_check(
21962223 // this has no successor
21972224 assertions.clear ();
21982225 }
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+ }
21992239 else if (i.is_dead ())
22002240 {
22012241 if (enable_pointer_check || enable_pointer_primitive_check)
@@ -2225,24 +2265,7 @@ void goto_check_ct::goto_check(
22252265 function_identifier == goto_functionst::entry_point () &&
22262266 enable_memory_leak_check)
22272267 {
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);
22462269 }
22472270 }
22482271
0 commit comments