This is a request for feedback and a proof-of-concept, not something I intend to merge as-is. It would be nice if gcc, maybe just under some circumstances, always generated an else-block for coverage purposes.
I am working on the MC/DC support by CFG analysis for a while https://gcc.gnu.org/pipermail/gcc-patches/2023-June/621449.html and have ironed out a lot of problems. The last problem I know about, which is impossible to actually fix right now, is the "fusing" of nested ifs. Here is an example: if (a) if (b) if (c) { ... } // 3 conditions, 6 outcomes if (a && b && c) { ... } // 3 conditions, 6 outcomes These form isomorphic CFGs which means there is no way for my algorithm to distinguish them. This is sort-of acceptable since the coverage measurements more accurately measure the semantics (and not the syntax), but this also happens when there is code in-between the nesting: if (a) // measures to 2 conditions, 4 outcomes { a += b * 10; b -= a + 2; if (b) { ... } } You would expect this to be measured as: if (a) // 1 condition, 2 outcomes { a += b * 10; b -= a + 2; if (b) // 1 condition, 2 outcomes { ... } } The source of the problem is the missing (or empty) else block, as the algorithm uses the outcome (then/else) edges to determine the limits of expressions. If, however, the else blocks are generated, the conditions are counted as you would expect. So I have a few questions: 1. Is something like this even acceptable? The semantics of the program should not change, assuming the else-block only exists but is without significant behavior. It will only be generated if there is no explicit else in source. 2. Should this only be generated when necessary (e.g. under condition coverage? No optimization?) 3. I used a simple int-init { int __mcdc_barrier = 0; } but there might be better contents for the block that does not add anything operationally. I am not very familiar with this part of gcc and would like to see someting better. Any suggestions? --- gcc/gimplify.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc index ade6e335da7..43af38df742 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -4370,6 +4370,14 @@ gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback) enum tree_code pred_code; gimple_seq seq = NULL; + if (TREE_OPERAND (expr, 2) == NULL_TREE) + { + tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier + ("__mcdc_barrier"), integer_type_node); + tree val = build_int_cst (integer_type_node, 0); + TREE_OPERAND (expr, 2) = build2 (INIT_EXPR, TREE_TYPE (var), var, val); + } + /* If this COND_EXPR has a value, copy the values into a temporary within the arms. */ if (!VOID_TYPE_P (type)) -- 2.30.2