analyzer: ensure .dot output is valid for an empty BB
authorDavid Malcolm <dmalcolm@redhat.com>
Fri, 20 Dec 2019 18:29:56 +0000 (13:29 -0500)
committerDavid Malcolm <dmalcolm@redhat.com>
Wed, 15 Jan 2020 01:47:21 +0000 (20:47 -0500)
This patch fixes an issue with the output of -fdump-analyzer-supergraph
on BBs with no statements, where the resulting files were unreadable by
dot e.g.:

Error: syntax error in line 1
... <TABLE BORDER="0"></TABLE> ...
in label of node node_10

gcc/analyzer/ChangeLog:
* supergraph.cc (supernode::dump_dot): Ensure that the TABLE
element has at least one TR.

gcc/testsuite/ChangeLog:
* gcc.dg/analyzer/dot-output.c: Add test coverage for a BB with
no statements.

gcc/analyzer/ChangeLog
gcc/analyzer/supergraph.cc
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/analyzer/dot-output.c

index 2f91cd1..08c16b7 100644 (file)
@@ -1,5 +1,10 @@
 2020-01-14  David Malcolm  <dmalcolm@redhat.com>
 
+       * supergraph.cc (supernode::dump_dot): Ensure that the TABLE
+       element has at least one TR.
+
+2020-01-14  David Malcolm  <dmalcolm@redhat.com>
+
        PR analyzer/58237
        * engine.cc (leak_stmt_finder::find_stmt): Use get_pure_location
        when comparing against UNKNOWN_LOCATION.
index fd905ea..1dcc274 100644 (file)
@@ -450,6 +450,8 @@ supernode::dump_dot (graphviz_out *gv, const dump_args_t &args) const
   pp_string (pp, "<TABLE BORDER=\"0\">");
   pp_write_text_to_stream (pp);
 
+  bool had_row = false;
+
   if (m_returning_call)
     {
       gv->begin_tr ();
@@ -464,18 +466,22 @@ supernode::dump_dot (graphviz_out *gv, const dump_args_t &args) const
       if (args.m_node_annotator)
        args.m_node_annotator->add_stmt_annotations (gv, m_returning_call);
       pp_newline (pp);
+
+      had_row = true;
     }
 
   if (entry_p ())
     {
       pp_string (pp, "<TR><TD>ENTRY</TD></TR>");
       pp_newline (pp);
+      had_row = true;
     }
 
   if (return_p ())
     {
       pp_string (pp, "<TR><TD>EXIT</TD></TR>");
       pp_newline (pp);
+      had_row = true;
     }
 
   /* Phi nodes.  */
@@ -492,6 +498,7 @@ supernode::dump_dot (graphviz_out *gv, const dump_args_t &args) const
        args.m_node_annotator->add_stmt_annotations (gv, stmt);
 
       pp_newline (pp);
+      had_row = true;
     }
 
   /* Statements.  */
@@ -508,6 +515,15 @@ supernode::dump_dot (graphviz_out *gv, const dump_args_t &args) const
        args.m_node_annotator->add_stmt_annotations (gv, stmt);
 
       pp_newline (pp);
+      had_row = true;
+    }
+
+  /* Graphviz requires a TABLE element to have at least one TR
+     (and each TR to have at least one TD).  */
+  if (!had_row)
+    {
+      pp_string (pp, "<TR><TD>(empty)</TD></TR>");
+      pp_newline (pp);
     }
 
   pp_string (pp, "</TABLE>>];\n\n");
index ac0cd2d..135dae0 100644 (file)
@@ -1,5 +1,10 @@
 2020-01-14  David Malcolm  <dmalcolm@redhat.com>
 
+       * gcc.dg/analyzer/dot-output.c: Add test coverage for a BB with
+       no statements.
+
+2020-01-14  David Malcolm  <dmalcolm@redhat.com>
+
        PR analyzer/58237
        * gcc.dg/analyzer/file-paths-1.c: New test.
 
index 586e144..25cb31f 100644 (file)
@@ -27,6 +27,22 @@ int *test (int *buf, int n, int *out)
   return result;
 }
 
+/* Test that we can generate valid .dot files given a BB with no
+   statements.  */
+extern int func ();
+int test_2 (void)
+{
+  int c1;
+  do
+    {
+      c1 = func ();
+      if (c1 == '\0')
+       break;
+    }
+  while (c1);
+  return c1;
+}
+
 /* { dg-final { dg-check-dot "dot-output.c.callgraph.dot" } } */
 /* { dg-final { dg-check-dot "dot-output.c.eg.dot" } } */
 /* { dg-final { dg-check-dot "dot-output.c.state-purge.dot" } } */