Skip to content

Commit e34f966

Browse files
author
zhuyunxing
committed
coverage. MC/DC analysis ignores decisions with only one condition
1 parent da99de4 commit e34f966

File tree

1 file changed

+11
-4
lines changed

1 file changed

+11
-4
lines changed

compiler/rustc_mir_build/src/build/coverageinfo.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ impl MCDCState {
178178
fn record_conditions(&mut self, op: LogicalOp) {
179179
let parent_condition = self.decision_stack.pop_back().unwrap_or_default();
180180
let lhs_id = if parent_condition.condition_id == ConditionId::NONE {
181-
self.next_condition_id += 1;
181+
self.next_condition_id = 1;
182182
ConditionId::from(self.next_condition_id)
183183
} else {
184184
parent_condition.condition_id
@@ -249,7 +249,12 @@ impl Builder<'_, '_> {
249249
let condition_info = branch_info
250250
.mcdc_state
251251
.as_mut()
252-
.and_then(|state| state.decision_stack.pop_back())
252+
.and_then(|state| {
253+
// If mcdc is enabled but no condition recorded in the stack, the branch must be standalone.
254+
// In this case mc/dc is equivalent to branch coverage. Because each checked decision takes at least 1 byte
255+
// in global bitmap of the function, we'd better not to generate too many mc/dc statements if could.
256+
state.decision_stack.pop_back()
257+
})
253258
.unwrap_or_default();
254259

255260
let mut inject_branch_marker = |block: BasicBlock| {
@@ -283,7 +288,7 @@ impl Builder<'_, '_> {
283288
{
284289
assert!(
285290
mcdc_state.decision_stack.is_empty(),
286-
"All condition should have been checked before the decision ends"
291+
"All conditions should have been checked before the decision ends"
287292
);
288293

289294
let conditions_num = mcdc_state.next_condition_id;
@@ -292,7 +297,9 @@ impl Builder<'_, '_> {
292297

293298
match conditions_num {
294299
0 => {
295-
unreachable!("Decision with no conditions is not allowed");
300+
// By here means the decision has only one condition, mc/dc analysis could ignore it.
301+
// since mc/dc is equivalent to branch coverage in this case.
302+
return;
296303
}
297304
1..=MAX_CONDITIONS_NUM_IN_DECISION => {
298305
let span = self.thir[expr_id].span;

0 commit comments

Comments
 (0)