From 6efa57b186c1662c738b4d9b737267211c5c0845 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Tue, 7 Jul 2020 17:03:41 -0400
Subject: [PATCH 287/377] 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

