This is really a gcov/instrumentation bug, but it was filed under ipa.

We did filter out incoming complex edges, but didn't account for the
case where a block has multiple incoming edges without actually being a
conditional outcome.  We also need to check that we have >= 2 incoming
edges after filtering out the complex ones to make sure it is a (short
circuiting) before we try to compute the masking table.

        PR ipa/124462

gcc/ChangeLog:

        * tree-profile.cc (masking_vectors): Skip blocks with less than
        2 non-complex incoming edges.

gcc/testsuite/ChangeLog:

        * g++.dg/gcov/pr124462.C: New test.
---
 gcc/testsuite/g++.dg/gcov/pr124462.C | 29 ++++++++++++++++++++++++++++
 gcc/tree-profile.cc                  |  2 ++
 2 files changed, 31 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/gcov/pr124462.C

diff --git a/gcc/testsuite/g++.dg/gcov/pr124462.C 
b/gcc/testsuite/g++.dg/gcov/pr124462.C
new file mode 100644
index 00000000000..2ce19e3976b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gcov/pr124462.C
@@ -0,0 +1,29 @@
+/* PR ipa/124462 */
+/* { dg-options "-O -fcondition-coverage -fdump-tree-gimple-all" }  */
+/* { dg-do compile } */
+
+/* PR ipa/124462 is really a gcov/instrumentation bug.  This program creates
+   blocks with multiple incoming edges where one is complex, the exception ->
+   destructor, which isn't really the outcome of a conditional expression.  */
+
+void deallocate(char *, long);
+struct buffer {};
+void vformat_to(buffer, int, int);
+enum { inline_buffer_size };
+template <unsigned long = inline_buffer_size>
+struct basic_memory_buffer : buffer {
+  ~basic_memory_buffer() {
+    char *data;
+    if (data)
+      deallocate(data, 0);
+  }
+};
+template <unsigned long SIZE> int to_string(basic_memory_buffer<SIZE>);
+int vformat_fmt, vformat_args;
+void vformat() {
+  basic_memory_buffer<> buffer;
+  vformat_to(buffer, vformat_fmt, vformat_args);
+  to_string(buffer);
+}
+
+/* { dg-final { run-gcov pr124462.C } } */
diff --git a/gcc/tree-profile.cc b/gcc/tree-profile.cc
index 0499a31027c..6380240c0ca 100644
--- a/gcc/tree-profile.cc
+++ b/gcc/tree-profile.cc
@@ -542,6 +542,8 @@ masking_vectors (conds_ctx& ctx, array_slice<basic_block> 
blocks,
        for (edge e : b->preds)
          if (!(e->flags & EDGE_COMPLEX))
            ctx.edges.quick_push (contract_edge_up (e));
+       if (ctx.edges.length () < 2)
+         continue;
        ctx.edges.sort (topological_src_cmp, &ctx.top_index);
 
        for (size_t i0 = 0, i1 = 1; i1 != ctx.edges.length (); ++i0, ++i1)
-- 
2.47.3

Reply via email to