Description
Let's consider such code:
constexpr bool constant_bool() { return false; }
int mcdc_with_constant(bool a) {
if (a && constant_bool()) {
return 1;
} else {
return 0;
}
}
Because the decision cannot be evaluated to true
, no condition could be shown to be covered by MCDC.
The constant may be a template parameter or a platform-dependent variable. As a result, one of the two branches might be optimized out and there is no branch in practice.
So could we eliminate such conditions and decisions from mcdc? For example,
- For
a && CONST
, ifCONST==false
, conditiona
is treated asfolded
too. - For
a || CONST
, ifCONST==true
,a
will be taken as folded. (Just in mcdc, normal branch coverage could still count it) - For
a && (b || CONST)
, ifCONST==true
,b
is taken as folded.
Also if a decision can not be evaluated to the other value, we mark it as folded.
We can check value of CONST
in mcdc as long as the front end preserves the non-zero counter. For now clang assign Zero
to both Counter
and FalseCounter
if the condition was constant. By only setting the never reached counter to Zero
, we can ensure the constant is true
if its FalseCounter
is Zero
and vice versa. Then by analyzing the decision tree, conditions that would be never covered in meaning of mcdc can be found out and marked as folded too.