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