aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2019-12-20 13:29:56 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2020-01-14 20:47:21 -0500
commit718930c0c8f8d25d185cb65e38c79a19458b6628 (patch)
treeeb53b7615cfb8192762d2106feab3304ac17992d
parent8397af8ed0db685312e44117fd52316b57c2c129 (diff)
downloadgcc-718930c0c8f8d25d185cb65e38c79a19458b6628.zip
gcc-718930c0c8f8d25d185cb65e38c79a19458b6628.tar.gz
gcc-718930c0c8f8d25d185cb65e38c79a19458b6628.tar.bz2
analyzer: ensure .dot output is valid for an empty BB
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.
-rw-r--r--gcc/analyzer/ChangeLog5
-rw-r--r--gcc/analyzer/supergraph.cc16
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/dot-output.c16
4 files changed, 42 insertions, 0 deletions
diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog
index 2f91cd1..08c16b7 100644
--- a/gcc/analyzer/ChangeLog
+++ b/gcc/analyzer/ChangeLog
@@ -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.
diff --git a/gcc/analyzer/supergraph.cc b/gcc/analyzer/supergraph.cc
index fd905ea..1dcc274 100644
--- a/gcc/analyzer/supergraph.cc
+++ b/gcc/analyzer/supergraph.cc
@@ -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");
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ac0cd2d..135dae08 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/gcc.dg/analyzer/dot-output.c b/gcc/testsuite/gcc.dg/analyzer/dot-output.c
index 586e144..25cb31f 100644
--- a/gcc/testsuite/gcc.dg/analyzer/dot-output.c
+++ b/gcc/testsuite/gcc.dg/analyzer/dot-output.c
@@ -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" } } */