From 0f7b4d9fc3b5264748c2d9429ea5a73826e5bfdc Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Fri, 24 May 2019 18:34:17 -0400
Subject: [PATCH 67/67] FIXME: further region_model cleanups

---
 gcc/analyzer/impl-4.cc                          | 56 +++++++++++++++++--------
 gcc/testsuite/gcc.dg/analyzer/malloc-dedupe-1.c |  2 +
 2 files changed, 40 insertions(+), 18 deletions(-)

diff --git a/gcc/analyzer/impl-4.cc b/gcc/analyzer/impl-4.cc
index 1aff8f6..5089c16 100644
--- a/gcc/analyzer/impl-4.cc
+++ b/gcc/analyzer/impl-4.cc
@@ -2504,16 +2504,19 @@ program_state::prune_for_point (exploded_graph &eg,
 #endif
       purge_stats stats;
 
-      region_id_set purgeable_ssa_regions (new_state.m_region_model);
-      region_id frame_rid = new_state.m_region_model->get_current_frame_id ();
-      frame_region *frame
-	= new_state.m_region_model->get_region <frame_region>(frame_rid);
       const state_purge_map *pm = eg.get_purge_map ();
       if (pm)
 	{
+	  region_id_set purgeable_ssa_regions (new_state.m_region_model);
+	  region_id frame_rid
+	    = new_state.m_region_model->get_current_frame_id ();
+	  frame_region *frame
+	    = new_state.m_region_model->get_region <frame_region>(frame_rid);
+
 	  /* FIXME: move to a member of region_model, once the state_purge_map
 	     etc decls are visible there.  */
-	  auto_vec<tree> ssa_to_purge;
+
+	  auto_vec<tree> ssa_names_to_purge;
 	  for (frame_region::map_t::iterator iter = frame->m_map.begin ();
 	       iter != frame->m_map.end ();
 	       ++iter)
@@ -2527,24 +2530,24 @@ program_state::prune_for_point (exploded_graph &eg,
 		  if (!per_ssa.needed_at_point_p (flat_point))
 		    {
 		      purgeable_ssa_regions.add_region (rid);
-		      ssa_to_purge.safe_push (var);
-		      eg.log ("would purge RID: %i for %qE", rid.as_int (), var);
+		      ssa_names_to_purge.safe_push (var);
+		      eg.log ("purging RID: %i for %qE", rid.as_int (), var);
 		      // FIXME: we also need to remove the region from the map
-		      // note that we're mid-traversal
+		      // note that we're mid-traversal: this is done in unbind
+		      // below
 		    }
 		}
 	    }
 
-#if 0
-	  int i;
+	  /* Unbind the regions from the frame's map of vars-to-regions.  */
 	  tree var;
-	  FOR_EACH_VEC_ELT (ssa_to_purge, i, var)
+	  FOR_EACH_VEC_ELT (ssa_names_to_purge, i, var)
 	    frame->unbind (var);
 
-	  // TODO: actually purge the regions
+	  /* Purge the regions.  Nothing should point to them, and they
+	     should have no children, as they are for SSA names.  */
 	  new_state.m_region_model->purge_regions (purgeable_ssa_regions,
 						   &stats);
-#endif
 	}
 
       /* Purge unused svalues.  */
@@ -5473,11 +5476,16 @@ state_purge_per_ssa_name::process_point (const program_point &point,
 	  }
 
 	/* Add given pred to worklist.  */
-	if (point.m_from_edge->m_src)
-	  add_to_worklist
-	    (program_point::after_supernode (point.m_from_edge->m_src,
-					     call_string ()),
-	     worklist, logger);
+	if (point.m_from_edge)
+	  {
+	    if (point.m_from_edge->m_src)
+	      add_to_worklist
+		(program_point::after_supernode (point.m_from_edge->m_src,
+						 call_string ()),
+		 worklist, logger);
+	  }
+	else
+	  gcc_assert (snode->entry_p ());
       }
       break;
 
@@ -5535,6 +5543,18 @@ state_purge_per_ssa_name::process_point (const program_point &point,
 								pred,
 								call_string ()),
 			       worklist, logger);
+	    /* If no preds and it's the initial BB, add it, to ensure that we
+	       have "before supernode" for the initial ENTRY block, and don't
+	       erroneously purge SSA names for initial values of parameters.  */
+	    if (snode->entry_p ()
+		&& snode->m_preds.length () == 0)
+	      {
+		add_to_worklist
+		  (program_point::before_supernode (snode,
+						    NULL,
+						    call_string ()),
+		   worklist, logger);
+	      }
 	  }
       }
       break;
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-dedupe-1.c b/gcc/testsuite/gcc.dg/analyzer/malloc-dedupe-1.c
index 7eecadf..0121516 100644
--- a/gcc/testsuite/gcc.dg/analyzer/malloc-dedupe-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-dedupe-1.c
@@ -1,3 +1,5 @@
+/* { dg-additional-options "-fanalyzer-region-model" } */
+
 #include <stdlib.h>
 
 extern void foo (void);
-- 
1.8.5.3

