From d220d0fbbaa4c3a87f3d36eeb660f5bf63e84a86 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Thu, 25 Apr 2019 16:08:40 -0400
Subject: [PATCH 199/217] FIXME: impl-4: start generating diagnostic_paths; fix
 state transitions

---
 gcc/analyzer/impl-4.cc | 53 ++++++++++++++++++++++++++++++++++----------------
 1 file changed, 36 insertions(+), 17 deletions(-)

diff --git a/gcc/analyzer/impl-4.cc b/gcc/analyzer/impl-4.cc
index 3e71c6b..f923253 100644
--- a/gcc/analyzer/impl-4.cc
+++ b/gcc/analyzer/impl-4.cc
@@ -272,7 +272,7 @@ public:
 
   bool is_empty_p () const;
 
-  state_machine::state_t get_state (path_var pv);
+  state_machine::state_t get_state (path_var pv) const;
   void set_state (path_var pv, state_machine::state_t state);
 
 private:
@@ -588,9 +588,10 @@ sm_state_map::is_empty_p () const
 }
 
 state_machine::state_t
-sm_state_map::get_state (path_var pv)
+sm_state_map::get_state (path_var pv) const
 {
-  if (state_machine::state_t *slot = m_var_to_state.get (pv))
+  if (state_machine::state_t *slot
+      = const_cast <map_t &> (m_var_to_state).get (pv))
     return *slot;
   else
     return 0;
@@ -610,8 +611,10 @@ class impl_sm_context : public sm_context, public log_user
 public:
   impl_sm_context (const exploded_graph &eg,
 		   const exploded_node *node,
-		   sm_state_map *smap)
-  : log_user (eg.get_logger ()), m_eg (eg), m_node (node), m_smap (smap)
+		   const sm_state_map &old_smap,
+		   sm_state_map *new_smap)
+  : log_user (eg.get_logger ()), m_eg (eg), m_node (node),
+    m_old_smap (old_smap), m_new_smap (new_smap)
   {
   }
 
@@ -622,9 +625,9 @@ public:
 		      tree origin) FINAL OVERRIDE
   {
     path_var pv (var, 0); // FIXME: stack depth
-    state_machine::state_t current = m_smap->get_state (pv);
+    state_machine::state_t current = m_old_smap.get_state (pv);
     if (current == from)
-      m_smap->set_state (pv, to);
+      m_new_smap->set_state (pv, to);
   }
 
   void warn_for_state (const supernode *node, const gimple *stmt,
@@ -633,7 +636,7 @@ public:
   {
     gcc_assert (d); // take ownership
     path_var pv (var, 0); // FIXME: stack depth
-    state_machine::state_t current = m_smap->get_state (pv);
+    state_machine::state_t current = m_old_smap.get_state (pv);
     if (state == current)
       {
 	/* TODO: generate a path.  */
@@ -641,26 +644,40 @@ public:
 	   end, with one shortest_paths instance, and so finding
 	   the shortest path, rather than just the first path.  */
 	shortest_paths sp (m_eg);
-	auto_vec<const exploded_edge *> path;
-	sp.get_shortest_path (m_node, &path);
-	if (get_logger ())
-	  for (int i = 0; i < path.length (); i++)
-	    log ("EN %i -> EN %i",
-		 path[i]->m_src->m_index,
-		 path[i]->m_dest->m_index);
+	auto_vec<const exploded_edge *> exploded_path;
+	sp.get_shortest_path (m_node, &exploded_path);
+	pretty_printer *pp = global_dc->printer->clone ();
+	simple_diagnostic_path emission_path (pp);
+	for (int i = 0; i < exploded_path.length (); i++)
+	  {
+	    if (get_logger ())
+	      log ("EN %i -> EN %i",
+		   exploded_path[i]->m_src->m_index,
+		   exploded_path[i]->m_dest->m_index);
+	    exploded_node *node = exploded_path[i]->m_dest;
+	    if (node->m_ps.m_point.m_kind == PK_BEFORE_STMT)
+	      {
+		emission_path.add_event (node->m_ps.m_point.get_stmt ()->location,
+					 NULL_TREE, /* FIXME */
+					 0, /* FIXME */
+					 "FIXME");
+	      }
+	  }
 
 	gcc_rich_location rich_loc (stmt->location);
-	//rich_loc.set_path (&emission_path);
+	rich_loc.set_path (&emission_path);
 
 	auto_cfun sentinel (node->m_fun);
 	d->emit (&rich_loc);
+	delete pp;
       }
     delete d;
   }
 
   const exploded_graph &m_eg;
   const exploded_node *m_node;
-  sm_state_map *m_smap;
+  const sm_state_map &m_old_smap;
+  sm_state_map *m_new_smap;
 };
 
 ////////////////////////////////////////////////////////////////////////////
@@ -867,6 +884,7 @@ exploded_node::on_stmt (const exploded_graph &eg) const
   FOR_EACH_VEC_ELT (old_state.m_checker_states, i, smap)
     {
       impl_sm_context ctxt (eg, this,
+			    *old_state.m_checker_states[i],
 			    new_state.m_checker_states[i]);
       const state_machine &sm = m_ext_state.get_sm (i);
       sm.on_stmt (&ctxt, point.m_supernode, point.get_stmt ());
@@ -891,6 +909,7 @@ exploded_node::on_edge (const exploded_graph &eg,
   FOR_EACH_VEC_ELT (old_state.m_checker_states, i, smap)
     {
       impl_sm_context ctxt (eg, this,
+			    *old_state.m_checker_states[i],
 			    new_state.m_checker_states[i]);
       const state_machine &sm = m_ext_state.get_sm (i);
       sm.on_edge (&ctxt, last_stmt, succ);
-- 
1.8.5.3

