From 6efa57b186c1662c738b4d9b737267211c5c0845 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Tue, 7 Jul 2020 17:03:41 -0400 Subject: [PATCH 287/315] FIXME: introduce region_model2::impl_call_free --- gcc/analyzer/region-model2-impl-calls.cc | 33 ++++++++++++++++++++++++ gcc/analyzer/region-model2.cc | 30 ++------------------- gcc/analyzer/region-model2.h | 1 + 3 files changed, 36 insertions(+), 28 deletions(-) diff --git a/gcc/analyzer/region-model2-impl-calls.cc b/gcc/analyzer/region-model2-impl-calls.cc index 32ee3e7fd8e..274e44dbc3d 100644 --- a/gcc/analyzer/region-model2-impl-calls.cc +++ b/gcc/analyzer/region-model2-impl-calls.cc @@ -226,6 +226,39 @@ region_model2::impl_call_calloc (const call_details &cd) return true; } +/* Handle the on_call_post part of "free", after sm-handling. + + If the ptr points to an underlying heap region2, delete the region2, + poisoning pointers to it and region2s within it. + + We delay this until after sm-state has been updated so that the + sm-handling can transition all of the various casts of the pointer + to a "freed" state *before* we delete the related region2 here. + + This has to be done here so that the sm-handling can use the fact + that they point to the same region2 to establish that they are equal + (in region_model2::eval_condition_without_cm), and thus transition + all pointers to the region2 to the "freed" state together, regardless + of casts. */ + +void +region_model2::impl_call_free (const call_details &cd) +{ + const svalue2 *ptr_sval = cd.get_arg_svalue2 (0); + if (const region_svalue2 *ptr_to_region2_sval + = ptr_sval->dyn_cast_region_svalue2 ()) + { + /* If the ptr points to an underlying heap region2, delete it, + poisoning pointers. */ + const region2 *freed_reg = ptr_to_region2_sval->get_pointee (); + purge_stats2 stats; + unbind_region2_and_descendents (freed_reg, + POISON_KIND_FREED, + &stats, cd.get_ctxt ()->get_logger ()); + // TODO: do anything with stats? + } +} + /* Handle the on_call_pre part of "malloc". */ bool diff --git a/gcc/analyzer/region-model2.cc b/gcc/analyzer/region-model2.cc index 8fc7c04a635..e36d15e905c 100644 --- a/gcc/analyzer/region-model2.cc +++ b/gcc/analyzer/region-model2.cc @@ -5048,37 +5048,11 @@ region_model2::on_call_post (const gcall *call, bool unknown_side_effects, region_model2_context *ctxt) { - /* Update for "free" here, after sm-handling. - - If the ptr points to an underlying heap region2, delete the region2, - poisoning pointers to it and region2s within it. - - We delay this until after sm-state has been updated so that the - sm-handling can transition all of the various casts of the pointer - to a "freed" state *before* we delete the related region2 here. - - This has to be done here so that the sm-handling can use the fact - that they point to the same region2 to establish that they are equal - (in region_model2::eval_condition_without_cm), and thus transition - all pointers to the region2 to the "freed" state together, regardless - of casts. */ if (tree callee_fndecl = get_fndecl_for_call (call, ctxt)) if (is_named_call_p (callee_fndecl, "free", call, 1)) { - tree ptr = gimple_call_arg (call, 0); - const svalue2 *ptr_sval = get_rvalue (ptr, ctxt); - if (const region_svalue2 *ptr_to_region2_sval - = ptr_sval->dyn_cast_region_svalue2 ()) - { - /* If the ptr points to an underlying heap region2, delete it, - poisoning pointers. */ - const region2 *freed_reg = ptr_to_region2_sval->get_pointee (); - purge_stats2 stats; - unbind_region2_and_descendents (freed_reg, - POISON_KIND_FREED, - &stats, ctxt->get_logger ()); - // TODO: do anything with stats? - } + call_details cd (call, this, ctxt); + impl_call_free (cd); return; } diff --git a/gcc/analyzer/region-model2.h b/gcc/analyzer/region-model2.h index 566fc512879..d1271ffbeea 100644 --- a/gcc/analyzer/region-model2.h +++ b/gcc/analyzer/region-model2.h @@ -2313,6 +2313,7 @@ class region_model2 region_model2_context *ctxt); bool impl_call_builtin_expect (const call_details &cd); bool impl_call_calloc (const call_details &cd); + void impl_call_free (const call_details &cd); bool impl_call_malloc (const call_details &cd); bool impl_call_memset (const call_details &cd); bool impl_call_strlen (const call_details &cd); -- 2.26.2