Skip to content

Commit 4df3f02

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 cf9db0d commit 4df3f02

File tree

2 files changed

+44
-22
lines changed

2 files changed

+44
-22
lines changed

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
}

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)