From 6eae5207542325289f3370809dab9def17ad00d5 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Tue, 19 May 2020 09:45:01 -0400
Subject: [PATCH 146/237] FIXME: get signal-1.c to work

---
 gcc/analyzer/checker-path.cc  |  1 -
 gcc/analyzer/program-state.cc | 17 ++++++--
 gcc/analyzer/program-state.h  |  1 +
 gcc/analyzer/region-model2.cc | 35 +++++++++++++++++
 gcc/analyzer/region-model2.h  |  2 +
 gcc/analyzer/sm-signal.cc     |  4 +-
 gcc/analyzer/store2.cc        | 74 ++++++++++++++++++++++++++++++++---
 gcc/analyzer/store2.h         |  1 +
 8 files changed, 124 insertions(+), 11 deletions(-)

diff --git a/gcc/analyzer/checker-path.cc b/gcc/analyzer/checker-path.cc
index dc8f59b5004..c07273460d5 100644
--- a/gcc/analyzer/checker-path.cc
+++ b/gcc/analyzer/checker-path.cc
@@ -227,7 +227,6 @@ state_change_event::state_change_event (const supernode *node,
   m_origin (origin),
   m_dst_state (dst_state)
 {
-  gcc_assert (m_var);
 }
 
 /* Implementation of diagnostic_event::get_desc vfunc for
diff --git a/gcc/analyzer/program-state.cc b/gcc/analyzer/program-state.cc
index ece7b7a58f2..4f7e174e37f 100644
--- a/gcc/analyzer/program-state.cc
+++ b/gcc/analyzer/program-state.cc
@@ -1270,7 +1270,7 @@ program_state::print (const extrinsic_state &ext_state,
 
 void
 program_state::dump_to_pp (const extrinsic_state &ext_state,
-			   bool simple, bool multiline,
+			   bool summarize, bool multiline,
 			   pretty_printer *pp) const
 {
   if (!multiline)
@@ -1282,7 +1282,7 @@ program_state::dump_to_pp (const extrinsic_state &ext_state,
 	pp_newline (pp);
       else
 	pp_string (pp, " {");
-      m_region_model->dump_to_pp (pp, simple);
+      m_region_model->dump_to_pp (pp, summarize);
       if (!multiline)
 	pp_string (pp, "}");
     }
@@ -1293,7 +1293,7 @@ program_state::dump_to_pp (const extrinsic_state &ext_state,
 	pp_newline (pp);
       else
 	pp_string (pp, " {");
-      m_region_model2->dump_to_pp (pp, simple, multiline);
+      m_region_model2->summarize_to_pp (pp, true);
       if (!multiline)
 	pp_string (pp, "}");
     }
@@ -1400,6 +1400,17 @@ program_state::push_frame (const extrinsic_state &ext_state,
     }
 }
 
+/* FIXME.  */
+
+function *
+program_state::get_current_function () const
+{
+  if (m_region_model2)
+    return m_region_model2->get_current_function ();
+  else
+    return m_region_model->get_current_function ();
+}
+
 /* Determine if following edge SUCC from ENODE is valid within the graph EG
    and update this state accordingly in-place.
 
diff --git a/gcc/analyzer/program-state.h b/gcc/analyzer/program-state.h
index f9e5065756f..e1d1adefc16 100644
--- a/gcc/analyzer/program-state.h
+++ b/gcc/analyzer/program-state.h
@@ -370,6 +370,7 @@ public:
   json::value *to_json () const;
 
   void push_frame (const extrinsic_state &ext_state, function *fun);
+  function * get_current_function () const;
 
   bool on_edge (exploded_graph &eg,
 		const exploded_node &enode,
diff --git a/gcc/analyzer/region-model2.cc b/gcc/analyzer/region-model2.cc
index d5c99f4f793..84b2d972d3a 100644
--- a/gcc/analyzer/region-model2.cc
+++ b/gcc/analyzer/region-model2.cc
@@ -3550,6 +3550,41 @@ region_model2::dump (bool simple) const
   dump (stderr, simple, true);
 }
 
+/* Dump a summary of this model to PP.  */
+
+void
+region_model2::summarize_to_pp (pretty_printer *pp, bool simple) const
+{
+  m_store.summarize_to_pp (pp, simple);
+
+  // FIXME:
+#if 0
+  /* Dump constraints.  */
+  pp_string (pp, "constraint_manager2:");
+  if (multiline)
+    pp_newline (pp);
+  else
+    pp_string (pp, " {");
+  m_constraints2->dump_to_pp (pp, multiline);
+  if (!multiline)
+    pp_string (pp, "}");
+#endif
+}
+
+/* Dump a summary of this model to stderr.  */
+
+DEBUG_FUNCTION void
+region_model2::summarize (bool simple) const
+{
+  pretty_printer pp;
+  pp_format_decoder (&pp) = default_tree_printer;
+  pp_show_color (&pp) = pp_show_color (global_dc->printer);
+  pp.buffer->stream = stderr;
+  summarize_to_pp (&pp, simple);
+  pp_newline (&pp);
+  pp_flush (&pp);
+}
+
 /* Dump RMODEL fully to stderr (i.e. without summarization).  */
 
 DEBUG_FUNCTION void
diff --git a/gcc/analyzer/region-model2.h b/gcc/analyzer/region-model2.h
index f99779b0fbd..06daaa6179e 100644
--- a/gcc/analyzer/region-model2.h
+++ b/gcc/analyzer/region-model2.h
@@ -1761,6 +1761,8 @@ class region_model2
   void dump_to_pp (pretty_printer *pp, bool simple, bool multiline) const;
   void dump (FILE *fp, bool simple, bool multiline) const;
   void dump (bool simple) const;
+  void summarize_to_pp (pretty_printer *pp, bool simple) const;
+  void summarize (bool simple) const;
 
   void debug () const;
 
diff --git a/gcc/analyzer/sm-signal.cc b/gcc/analyzer/sm-signal.cc
index 269460172ec..6cbb10c8ab9 100644
--- a/gcc/analyzer/sm-signal.cc
+++ b/gcc/analyzer/sm-signal.cc
@@ -139,7 +139,7 @@ public:
 	&& change.m_new_state == m_sm.m_in_signal_handler)
       {
 	function *handler
-	  = change.m_event.m_dst_state.m_region_model->get_current_function ();
+	  = change.m_event.m_dst_state.get_current_function ();
 	return change.formatted_print ("registering %qD as signal handler",
 				       handler->decl);
       }
@@ -261,6 +261,8 @@ public:
 					handler_fun);
     state_entering_handler.m_checker_states[sm_idx]->set_global_state
       (m_sm.m_in_signal_handler);
+    state_entering_handler.m_checker_states2[sm_idx]->set_global_state
+      (m_sm.m_in_signal_handler);
 
     exploded_node *dst_enode = eg->get_or_create_node (entering_handler,
 						       state_entering_handler,
diff --git a/gcc/analyzer/store2.cc b/gcc/analyzer/store2.cc
index 6bc931b9ca3..0689c1d0768 100644
--- a/gcc/analyzer/store2.cc
+++ b/gcc/analyzer/store2.cc
@@ -738,6 +738,7 @@ store2::operator= (const store2 &other)
        iter != m_cluster_map.end ();
        ++iter)
     delete (*iter).second;
+  m_cluster_map.empty ();
 
   /* Deep copy.  TODO: replace with functional approach using immutable_map.  */
   for (cluster_map_t::iterator iter = other.m_cluster_map.begin ();
@@ -750,6 +751,7 @@ store2::operator= (const store2 &other)
       gcc_assert (c);
       m_cluster_map.put (reg, new binding_cluster2 (*c));
     }
+  return *this;
 }
 
 /* FIXME.  */
@@ -805,7 +807,7 @@ get_sorted_parent_regions (auto_vec<const region2 *> *out,
 /* FIXME.  */
 
 void
-store2::dump_to_pp (pretty_printer *pp, bool summarize, bool multiline) const
+store2::dump_to_pp (pretty_printer *pp, bool simple, bool multiline) const
 {
   /* Sort into some deterministic order.  */
   auto_vec<const region2 *> base_regions;
@@ -828,7 +830,7 @@ store2::dump_to_pp (pretty_printer *pp, bool summarize, bool multiline) const
     {
       gcc_assert (parent_reg);
       pp_string (pp, "clusters within ");
-      parent_reg->dump_to_pp (pp, summarize);
+      parent_reg->dump_to_pp (pp, simple);
       if (multiline)
 	pp_newline (pp);
       else
@@ -846,18 +848,18 @@ store2::dump_to_pp (pretty_printer *pp, bool summarize, bool multiline) const
 	  if (multiline)
 	    {
 	      pp_string (pp, "  cluster for: ");
-	      base_reg->dump_to_pp (pp, summarize);
+	      base_reg->dump_to_pp (pp, simple);
 	      pp_newline (pp);
-	      cluster->dump_to_pp (pp, summarize, multiline);
+	      cluster->dump_to_pp (pp, simple, multiline);
 	    }
 	  else
 	    {
 	      if (i > 0)
 		pp_string (pp, ", ");
 	      pp_string (pp, "base region: {");
-	      base_reg->dump_to_pp (pp, summarize);
+	      base_reg->dump_to_pp (pp, simple);
 	      pp_string (pp, "} has cluster: {");
-	      cluster->dump_to_pp (pp, summarize, multiline);
+	      cluster->dump_to_pp (pp, simple, multiline);
 	      pp_string (pp, "}");
 	    }
 	}
@@ -880,6 +882,66 @@ store2::dump (bool simple) const
   pp_flush (&pp);
 }
 
+/* FIXME.  */
+
+void
+store2::summarize_to_pp (pretty_printer *pp, bool simple) const
+{
+#if 1
+  // TODO
+#else
+  /* Sort into some deterministic order.  */
+  auto_vec<const region2 *> base_regions;
+  for (cluster_map_t::iterator iter = m_cluster_map.begin ();
+       iter != m_cluster_map.end (); ++iter)
+    {
+      const region2 *base_reg = (*iter).first;
+      base_regions.safe_push (base_reg);
+    }
+  base_regions.qsort (region2::cmp_ptrs);
+
+  /* Gather clusters, organize by parent region, so that we can group
+     together locals, globals, etc.  */
+  auto_vec<const region2 *> parent_regions;
+  get_sorted_parent_regions (&parent_regions, base_regions);
+
+  const region2 *parent_reg;
+  unsigned i;
+  FOR_EACH_VEC_ELT (parent_regions, i, parent_reg)
+    {
+      gcc_assert (parent_reg);
+      pp_string (pp, "clusters within ");
+      parent_reg->dump_to_pp (pp, simple);
+
+      const region2 *base_reg;
+      unsigned j;
+      FOR_EACH_VEC_ELT (base_regions, j, base_reg)
+	{
+	  /* This is O(N * M), but N ought to be small.  */
+	  if (base_reg->get_parent_region () != parent_reg)
+	    continue;
+	  binding_cluster2 *cluster
+	    = *const_cast<cluster_map_t &> (m_cluster_map).get (base_reg);
+	  if (multiline)
+	    {
+	      pp_string (pp, "  cluster for: ");
+	      base_reg->dump_to_pp (pp, simple);
+	      pp_newline (pp);
+	      cluster->dump_to_pp (pp, simple, multiline);
+	    }
+	  else
+	    {
+	      if (i > 0)
+		pp_string (pp, ", ");
+	      base_reg->dump_to_pp (pp, simple);
+	      pp_string (pp, ": ");
+	      cluster->dump_to_pp (pp, simple, false);
+	    }
+	}
+    }
+#endif
+}
+
 const svalue2 *
 store2::get_any_binding (store2_manager *mgr, const region2 *reg)
 {
diff --git a/gcc/analyzer/store2.h b/gcc/analyzer/store2.h
index 361d198f9a8..c73e209e998 100644
--- a/gcc/analyzer/store2.h
+++ b/gcc/analyzer/store2.h
@@ -290,6 +290,7 @@ public:
 
   void dump_to_pp (pretty_printer *pp, bool summarize, bool multiline) const;
   void dump (bool simple) const;
+  void summarize_to_pp (pretty_printer *pp, bool simple) const;
 
   const svalue2 *get_direct_binding (store2_manager *mgr, const region2 *reg);
   const svalue2 *get_default_binding (store2_manager *mgr, const region2 *reg);
-- 
2.26.2

