Skip to content

Commit 98e0fc7

Browse files
committed
coverage: Make MCDC take in account last RHS of condition-coverage
Condition coverage extends branch coverage to treat the specific case of last operands of boolean decisions not involved in control flow. This is ultimately made for MCDC to be exhaustive on all boolean expressions. This patch adds a call to `visit_branch_coverage_operation` to track the top-level operand of the said decisions, and changes `visit_coverage_standalone_condition` so MCDC branch registration is called when enabled on these _last RHS_ cases.
1 parent 5c94140 commit 98e0fc7

File tree

2 files changed

+44
-22
lines changed

2 files changed

+44
-22
lines changed

Diff for: compiler/rustc_mir_build/src/build/coverageinfo.rs

+39-21
Original file line numberDiff line numberDiff line change
@@ -117,17 +117,37 @@ impl BranchInfoBuilder {
117117
}
118118
}
119119

120-
fn add_two_way_branch<'tcx>(
120+
fn register_two_way_branch<'tcx>(
121121
&mut self,
122+
tcx: TyCtxt<'tcx>,
122123
cfg: &mut CFG<'tcx>,
123124
source_info: SourceInfo,
124125
true_block: BasicBlock,
125126
false_block: BasicBlock,
126127
) {
127-
let true_marker = self.markers.inject_block_marker(cfg, source_info, true_block);
128-
let false_marker = self.markers.inject_block_marker(cfg, source_info, false_block);
128+
let this = self;
129129

130-
self.branch_spans.push(BranchSpan { span: source_info.span, true_marker, false_marker });
130+
// Separate path for handling branches when MC/DC is enabled.
131+
if let Some(mcdc_info) = this.mcdc_info.as_mut() {
132+
let inject_block_marker =
133+
|source_info, block| this.markers.inject_block_marker(cfg, source_info, block);
134+
mcdc_info.visit_evaluated_condition(
135+
tcx,
136+
source_info,
137+
true_block,
138+
false_block,
139+
inject_block_marker,
140+
);
141+
} else {
142+
let true_marker = this.markers.inject_block_marker(cfg, source_info, true_block);
143+
let false_marker = this.markers.inject_block_marker(cfg, source_info, false_block);
144+
145+
this.branch_spans.push(BranchSpan {
146+
span: source_info.span,
147+
true_marker,
148+
false_marker,
149+
});
150+
}
131151
}
132152

133153
pub(crate) fn into_done(self) -> Option<Box<mir::coverage::BranchInfo>> {
@@ -204,7 +224,14 @@ impl<'tcx> Builder<'_, 'tcx> {
204224
mir::TerminatorKind::if_(mir::Operand::Copy(place), true_block, false_block),
205225
);
206226

207-
branch_info.add_two_way_branch(&mut self.cfg, source_info, true_block, false_block);
227+
// Separate path for handling branches when MC/DC is enabled.
228+
branch_info.register_two_way_branch(
229+
self.tcx,
230+
&mut self.cfg,
231+
source_info,
232+
true_block,
233+
false_block,
234+
);
208235

209236
let join_block = self.cfg.start_new_block();
210237
self.cfg.goto(true_block, source_info, join_block);
@@ -235,21 +262,12 @@ impl<'tcx> Builder<'_, 'tcx> {
235262

236263
let source_info = SourceInfo { span: self.thir[expr_id].span, scope: self.source_scope };
237264

238-
// Separate path for handling branches when MC/DC is enabled.
239-
if let Some(mcdc_info) = branch_info.mcdc_info.as_mut() {
240-
let inject_block_marker = |source_info, block| {
241-
branch_info.markers.inject_block_marker(&mut self.cfg, source_info, block)
242-
};
243-
mcdc_info.visit_evaluated_condition(
244-
self.tcx,
245-
source_info,
246-
then_block,
247-
else_block,
248-
inject_block_marker,
249-
);
250-
return;
251-
}
252-
253-
branch_info.add_two_way_branch(&mut self.cfg, source_info, then_block, else_block);
265+
branch_info.register_two_way_branch(
266+
self.tcx,
267+
&mut self.cfg,
268+
source_info,
269+
then_block,
270+
else_block,
271+
);
254272
}
255273
}

Diff for: compiler/rustc_mir_build/src/build/expr/into.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
147147
}
148148
ExprKind::LogicalOp { op, lhs, rhs } => {
149149
let condition_scope = this.local_scope();
150-
let source_info = this.source_info(expr.span);
150+
let expr_span = expr.span;
151+
let source_info = this.source_info(expr_span);
152+
153+
this.visit_coverage_branch_operation(op, expr_span);
154+
151155
// We first evaluate the left-hand side of the predicate ...
152156
let (then_block, else_block) =
153157
this.in_if_then_scope(condition_scope, expr.span, |this| {

0 commit comments

Comments
 (0)