diff options
author | David Malcolm <dmalcolm@redhat.com> | 2019-12-20 13:29:56 -0500 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2020-01-14 20:47:21 -0500 |
commit | 718930c0c8f8d25d185cb65e38c79a19458b6628 (patch) | |
tree | eb53b7615cfb8192762d2106feab3304ac17992d /gcc | |
parent | 8397af8ed0db685312e44117fd52316b57c2c129 (diff) | |
download | gcc-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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/analyzer/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/analyzer/supergraph.cc | 16 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/analyzer/dot-output.c | 16 |
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" } } */ |