Depth first order is insufficient to process expressions in the right order when there are setjmps in optimized builds. This would create complex paths from the root past conditions and into the middle of boolean expressions. Traversing the graph in topological order restores the expectation that expressions will be processed top-down. --- gcc/testsuite/gcc.misc-tests/gcov-23.c | 26 ++++++++++++++++++++++++++ gcc/tree-profile.cc | 1 + 2 files changed, 27 insertions(+)
diff --git a/gcc/testsuite/gcc.misc-tests/gcov-23.c b/gcc/testsuite/gcc.misc-tests/gcov-23.c index 856e97f5088..e5b56a5aa44 100644 --- a/gcc/testsuite/gcc.misc-tests/gcov-23.c +++ b/gcc/testsuite/gcc.misc-tests/gcov-23.c @@ -1,5 +1,8 @@ /* { dg-options "-fprofile-conditions -ftest-coverage -O2 -c" } */ +#include <setjmp.h> +jmp_buf buf; + int id (int); int idp (int *); int err; @@ -120,4 +123,27 @@ mcdc003 (const char *locale) return 1; } +/* Adapted from jxl 0.8.2 lib/extras/dec/apng.cc processing_start (). + This created a graph where depth-first traversal of the CFG would not + process nodes in the wrong order (the extra control inserted from setjmp + created a path of complexes from root to !b without going through !a). + + This only happened under optimization. */ +int +mcdc004 (int a, int b) +{ + a = id (a); + b = id (b); + + if (a || b) /* conditions(0/4) true(0 1) false(0 1) */ + /* conditions(end) */ + return 1; + + if (setjmp (buf)) /* conditions(0/2) true(0) false(0) */ + /* conditions(end) */ + return 1; + + return 0; +} + /* { dg-final { run-gcov conditions { --conditions gcov-23.c } } } */ diff --git a/gcc/tree-profile.cc b/gcc/tree-profile.cc index d1d7265cd1c..8bf280dc018 100644 --- a/gcc/tree-profile.cc +++ b/gcc/tree-profile.cc @@ -1045,6 +1045,7 @@ find_conditions (struct function *fn) int n = dfs_enumerate_from (entry, 0, yes, dfs.address (), nblocks, exit); dfs.truncate (n); make_index_map (dfs, nblocks, ctx.B1, ctx.index_map); + dfs.sort (cmp_index_map, &ctx.index_map); /* Visit all reachable nodes and collect conditions. DFS order is important so the first node of a boolean expression is visited first -- 2.30.2