You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This issue aims to be a discussion about the implementation of branch coverage, to follow up the discussions in #79649 and #124118.
In the following code example, the current implementation of branch coverage does not instrument the outcome of b in the indirect function, because it has no impact on the control flow of the program and is just assigned to v. a, however, creates a conditional evaluation of b because of the short circuits semantics and thus creates a branch in the control flow.
fndirect(a:bool,b:bool){if a || b {println!("success");}}fnindirect(a:bool,b:bool){let v = a || b;if v {println!("success");}}#[coverage(off)]fnmain(){direct(true,false);direct(false,false);indirect(true,false);indirect(false,false);}
Even though this instrumentation is "branch coverage" according to the definition, there are several reasons for which one would expect b to be instrumented as well :
MC/DC coverage instrumentation depends on branch coverage, and in certification context, MC/DC coverage implies that all the conditions in all the boolean expressions with 2+ operands are instrumented.
@Zalathar gave pertinent reasons on why the "instrument b" behavior might not suit everyone's needs, one being that it implies inserting branches in the MIR that are not here by default. Roughly speaking, this would imply that the MIR of the expression would look like the one of let x = if a || b { true } else { false }; rather than let x = if a { b } else { false };.
In order to give the choice to the user, I think we could implement this behavior under another compilation flags: -Z coverage-options=condition.
This idea is that condition coverage instruments the outcome of each condition inside boolean expressions:
when the expression has 2+ conditions and is outside of a control flow structure
anytime the expression is in a control flow structure.
Basically, this is branch coverage with the special case of b being instrumented.
In terms of implementation, I think the easiest would be to make condition imply branch coverage, and treat the special case only when condition is enabled.
This issue aims to be a discussion about the implementation of branch coverage, to follow up the discussions in #79649 and #124118.
In the following code example, the current implementation of branch coverage does not instrument the outcome of
bin theindirectfunction, because it has no impact on the control flow of the program and is just assigned tov.a, however, creates a conditional evaluation ofbbecause of the short circuits semantics and thus creates a branch in the control flow.Even though this instrumentation is "branch coverage" according to the definition, there are several reasons for which one would expect
bto be instrumented as well :@Zalathar gave pertinent reasons on why the "instrument
b" behavior might not suit everyone's needs, one being that it implies inserting branches in the MIR that are not here by default. Roughly speaking, this would imply that the MIR of the expression would look like the one oflet x = if a || b { true } else { false };rather thanlet x = if a { b } else { false };.In order to give the choice to the user, I think we could implement this behavior under another compilation flags:
-Z coverage-options=condition.This idea is that condition coverage instruments the outcome of each condition inside boolean expressions:
Basically, this is branch coverage with the special case of
bbeing instrumented.In terms of implementation, I think the easiest would be to make
conditionimplybranchcoverage, and treat the special case only whenconditionis enabled.