diff mbox series

[committed] analyzer: show saved diagnostics as nodes in .eg.dot dumps

Message ID 20220615215120.1704515-1-dmalcolm@redhat.com
State New
Headers show
Series [committed] analyzer: show saved diagnostics as nodes in .eg.dot dumps | expand

Commit Message

David Malcolm June 15, 2022, 9:51 p.m. UTC
I've been using this tweak to the output of
-fdump-analyzer-exploded-graph in my working copies for a while;
the extra red nodes make it *much* easier to find the places where
diagnostics are being emitted (or rejected by the diagnostic_manager).

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as r13-1117-gc540077a3bf600.

gcc/analyzer/ChangeLog:
	* diagnostic-manager.cc (saved_diagnostic::dump_dot_id): New.
	(saved_diagnostic::dump_as_dot_node): New.
	* diagnostic-manager.h (saved_diagnostic::dump_dot_id): New decl.
	(saved_diagnostic::dump_as_dot_node): New decl.
	* engine.cc (exploded_node::dump_dot): Add nodes for saved
	diagnostics.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
---
 gcc/analyzer/diagnostic-manager.cc | 62 ++++++++++++++++++++++++++++++
 gcc/analyzer/diagnostic-manager.h  |  3 ++
 gcc/analyzer/engine.cc             | 21 ++++++++++
 3 files changed, 86 insertions(+)
diff mbox series

Patch

diff --git a/gcc/analyzer/diagnostic-manager.cc b/gcc/analyzer/diagnostic-manager.cc
index e90cd001f1a..4e96a3667e3 100644
--- a/gcc/analyzer/diagnostic-manager.cc
+++ b/gcc/analyzer/diagnostic-manager.cc
@@ -742,6 +742,68 @@  saved_diagnostic::to_json () const
   return sd_obj;
 }
 
+/* Dump this to PP in a form suitable for use as an id in .dot output.  */
+
+void
+saved_diagnostic::dump_dot_id (pretty_printer *pp) const
+{
+  pp_printf (pp, "sd_%i", m_idx);
+}
+
+/* Dump this to PP in a form suitable for use as a node in .dot output.  */
+
+void
+saved_diagnostic::dump_as_dot_node (pretty_printer *pp) const
+{
+  dump_dot_id (pp);
+  pp_printf (pp,
+	     " [shape=none,margin=0,style=filled,fillcolor=\"red\",label=\"");
+  pp_write_text_to_stream (pp);
+
+  /* Node label.  */
+  pp_printf (pp, "DIAGNOSTIC: %s (sd: %i)\n",
+	     m_d->get_kind (), m_idx);
+  if (m_sm)
+    {
+      pp_printf (pp, "sm: %s", m_sm->get_name ());
+      if (m_state)
+	{
+	  pp_printf (pp, "; state: ");
+	  m_state->dump_to_pp (pp);
+	}
+      pp_newline (pp);
+    }
+  if (m_stmt)
+    {
+      pp_string (pp, "stmt: ");
+      pp_gimple_stmt_1 (pp, m_stmt, 0, (dump_flags_t)0);
+      pp_newline (pp);
+    }
+  if (m_var)
+    pp_printf (pp, "var: %qE\n", m_var);
+  if (m_sval)
+    {
+      pp_string (pp, "sval: ");
+      m_sval->dump_to_pp (pp, true);
+      pp_newline (pp);
+    }
+  if (m_best_epath)
+    pp_printf (pp, "path length: %i\n", get_epath_length ());
+
+  pp_write_text_as_dot_label_to_stream (pp, /*for_record=*/true);
+  pp_string (pp, "\"];\n\n");
+
+  /* Show links to duplicates.  */
+  for (auto iter : m_duplicates)
+    {
+      dump_dot_id (pp);
+      pp_string (pp, " -> ");
+      iter->dump_dot_id (pp);
+      pp_string (pp, " [style=\"dotted\" arrowhead=\"none\"];");
+      pp_newline (pp);
+    }
+}
+
 /* Use PF to find the best exploded_path for this saved_diagnostic,
    and store it in m_best_epath.
    If m_stmt is still NULL, use m_stmt_finder on the epath to populate
diff --git a/gcc/analyzer/diagnostic-manager.h b/gcc/analyzer/diagnostic-manager.h
index fc5dc043c78..b9bb7c8c254 100644
--- a/gcc/analyzer/diagnostic-manager.h
+++ b/gcc/analyzer/diagnostic-manager.h
@@ -46,6 +46,9 @@  public:
 
   json::object *to_json () const;
 
+  void dump_dot_id (pretty_printer *pp) const;
+  void dump_as_dot_node (pretty_printer *pp) const;
+
   const feasibility_problem *get_feasibility_problem () const
   {
     return m_problem;
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index 5ccfedf9a44..ca86166173c 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -1209,6 +1209,27 @@  exploded_node::dump_dot (graphviz_out *gv, const dump_args_t &args) const
   pp_write_text_as_dot_label_to_stream (pp, /*for_record=*/true);
 
   pp_string (pp, "\"];\n\n");
+
+  /* It can be hard to locate the saved diagnostics as text within the
+     enode nodes, so add extra nodes to the graph for each saved_diagnostic,
+     highlighted in red.
+     Compare with dump_saved_diagnostics.  */
+  {
+    unsigned i;
+    const saved_diagnostic *sd;
+    FOR_EACH_VEC_ELT (m_saved_diagnostics, i, sd)
+      {
+	sd->dump_as_dot_node (pp);
+
+	/* Add edge connecting this enode to the saved_diagnostic.  */
+	dump_dot_id (pp);
+	pp_string (pp, " -> ");
+	sd->dump_dot_id (pp);
+	pp_string (pp, " [style=\"dotted\" arrowhead=\"none\"];");
+	pp_newline (pp);
+      }
+  }
+
   pp_flush (pp);
 }