Skip to content

Commit a7cf6ec

Browse files
authored
Rollup merge of #125766 - RenjiSann:fresh-mcdc-branch-on-bool, r=nnethercote
MCDC Coverage: instrument last boolean RHS operands from condition coverage Fresh PR from #124652 -- This PR ensures that the top-level boolean expressions that are not part of the control flow are correctly instrumented thanks to condition coverage. See discussion on #124120. Depends on `@Zalathar` 's condition coverage implementation #125756.
2 parents 25d47fe + e15adef commit a7cf6ec

File tree

5 files changed

+526
-23
lines changed

5 files changed

+526
-23
lines changed

compiler/rustc_mir_build/src/build/coverageinfo.rs

+45-23
Original file line numberDiff line numberDiff line change
@@ -118,17 +118,35 @@ impl BranchInfoBuilder {
118118
}
119119
}
120120

121-
fn add_two_way_branch<'tcx>(
121+
fn register_two_way_branch<'tcx>(
122122
&mut self,
123+
tcx: TyCtxt<'tcx>,
123124
cfg: &mut CFG<'tcx>,
124125
source_info: SourceInfo,
125126
true_block: BasicBlock,
126127
false_block: BasicBlock,
127128
) {
128-
let true_marker = self.markers.inject_block_marker(cfg, source_info, true_block);
129-
let false_marker = self.markers.inject_block_marker(cfg, source_info, false_block);
130-
131-
self.branch_spans.push(BranchSpan { span: source_info.span, true_marker, false_marker });
129+
// Separate path for handling branches when MC/DC is enabled.
130+
if let Some(mcdc_info) = self.mcdc_info.as_mut() {
131+
let inject_block_marker =
132+
|source_info, block| self.markers.inject_block_marker(cfg, source_info, block);
133+
mcdc_info.visit_evaluated_condition(
134+
tcx,
135+
source_info,
136+
true_block,
137+
false_block,
138+
inject_block_marker,
139+
);
140+
} else {
141+
let true_marker = self.markers.inject_block_marker(cfg, source_info, true_block);
142+
let false_marker = self.markers.inject_block_marker(cfg, source_info, false_block);
143+
144+
self.branch_spans.push(BranchSpan {
145+
span: source_info.span,
146+
true_marker,
147+
false_marker,
148+
});
149+
}
132150
}
133151

134152
pub(crate) fn into_done(self) -> Option<Box<mir::coverage::BranchInfo>> {
@@ -205,7 +223,14 @@ impl<'tcx> Builder<'_, 'tcx> {
205223
mir::TerminatorKind::if_(mir::Operand::Copy(place), true_block, false_block),
206224
);
207225

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

210235
let join_block = self.cfg.start_new_block();
211236
self.cfg.goto(true_block, source_info, join_block);
@@ -236,22 +261,13 @@ impl<'tcx> Builder<'_, 'tcx> {
236261

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

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

257273
/// If branch coverage is enabled, inject marker statements into `true_block`
@@ -270,6 +286,12 @@ impl<'tcx> Builder<'_, 'tcx> {
270286
// FIXME(#124144) This may need special handling when MC/DC is enabled.
271287

272288
let source_info = SourceInfo { span: pattern.span, scope: self.source_scope };
273-
branch_info.add_two_way_branch(&mut self.cfg, source_info, true_block, false_block);
289+
branch_info.register_two_way_branch(
290+
self.tcx,
291+
&mut self.cfg,
292+
source_info,
293+
true_block,
294+
false_block,
295+
);
274296
}
275297
}

compiler/rustc_mir_build/src/build/expr/into.rs

+3
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
150150
ExprKind::LogicalOp { op, lhs, rhs } => {
151151
let condition_scope = this.local_scope();
152152
let source_info = this.source_info(expr.span);
153+
154+
this.visit_coverage_branch_operation(op, expr.span);
155+
153156
// We first evaluate the left-hand side of the predicate ...
154157
let (then_block, else_block) =
155158
this.in_if_then_scope(condition_scope, expr.span, |this| {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
Function name: mcdc_non_control_flow::assign_3
2+
Raw bytes (89): 0x[01, 01, 09, 05, 07, 0b, 11, 09, 0d, 01, 05, 01, 05, 22, 11, 01, 05, 22, 11, 01, 05, 0a, 01, 16, 01, 00, 28, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 00, 03, 00, 0d, 00, 18, 30, 05, 22, 01, 00, 02, 00, 0d, 00, 0e, 22, 00, 12, 00, 13, 30, 1e, 11, 02, 03, 00, 00, 12, 00, 13, 1e, 00, 17, 00, 18, 30, 09, 0d, 03, 00, 00, 00, 17, 00, 18, 03, 01, 05, 01, 02]
3+
Number of files: 1
4+
- file 0 => global file 1
5+
Number of expressions: 9
6+
- expression 0 operands: lhs = Counter(1), rhs = Expression(1, Add)
7+
- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(4)
8+
- expression 2 operands: lhs = Counter(2), rhs = Counter(3)
9+
- expression 3 operands: lhs = Counter(0), rhs = Counter(1)
10+
- expression 4 operands: lhs = Counter(0), rhs = Counter(1)
11+
- expression 5 operands: lhs = Expression(8, Sub), rhs = Counter(4)
12+
- expression 6 operands: lhs = Counter(0), rhs = Counter(1)
13+
- expression 7 operands: lhs = Expression(8, Sub), rhs = Counter(4)
14+
- expression 8 operands: lhs = Counter(0), rhs = Counter(1)
15+
Number of file 0 mappings: 10
16+
- Code(Counter(0)) at (prev + 22, 1) to (start + 0, 40)
17+
- Code(Expression(0, Add)) at (prev + 1, 9) to (start + 0, 10)
18+
= (c1 + ((c2 + c3) + c4))
19+
- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
20+
- MCDCDecision { bitmap_idx: 0, conditions_num: 3 } at (prev + 0, 13) to (start + 0, 24)
21+
- MCDCBranch { true: Counter(1), false: Expression(8, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 13) to (start + 0, 14)
22+
true = c1
23+
false = (c0 - c1)
24+
- Code(Expression(8, Sub)) at (prev + 0, 18) to (start + 0, 19)
25+
= (c0 - c1)
26+
- MCDCBranch { true: Expression(7, Sub), false: Counter(4), condition_id: 2, true_next_id: 3, false_next_id: 0 } at (prev + 0, 18) to (start + 0, 19)
27+
true = ((c0 - c1) - c4)
28+
false = c4
29+
- Code(Expression(7, Sub)) at (prev + 0, 23) to (start + 0, 24)
30+
= ((c0 - c1) - c4)
31+
- MCDCBranch { true: Counter(2), false: Counter(3), condition_id: 3, true_next_id: 0, false_next_id: 0 } at (prev + 0, 23) to (start + 0, 24)
32+
true = c2
33+
false = c3
34+
- Code(Expression(0, Add)) at (prev + 1, 5) to (start + 1, 2)
35+
= (c1 + ((c2 + c3) + c4))
36+
37+
Function name: mcdc_non_control_flow::assign_3_bis
38+
Raw bytes (85): 0x[01, 01, 07, 07, 11, 09, 0d, 01, 05, 05, 09, 16, 1a, 05, 09, 01, 05, 0a, 01, 1b, 01, 00, 2c, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 00, 03, 00, 0d, 00, 18, 30, 05, 1a, 01, 03, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 16, 03, 00, 02, 00, 12, 00, 13, 13, 00, 17, 00, 18, 30, 0d, 11, 02, 00, 00, 00, 17, 00, 18, 03, 01, 05, 01, 02]
39+
Number of files: 1
40+
- file 0 => global file 1
41+
Number of expressions: 7
42+
- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(4)
43+
- expression 1 operands: lhs = Counter(2), rhs = Counter(3)
44+
- expression 2 operands: lhs = Counter(0), rhs = Counter(1)
45+
- expression 3 operands: lhs = Counter(1), rhs = Counter(2)
46+
- expression 4 operands: lhs = Expression(5, Sub), rhs = Expression(6, Sub)
47+
- expression 5 operands: lhs = Counter(1), rhs = Counter(2)
48+
- expression 6 operands: lhs = Counter(0), rhs = Counter(1)
49+
Number of file 0 mappings: 10
50+
- Code(Counter(0)) at (prev + 27, 1) to (start + 0, 44)
51+
- Code(Expression(0, Add)) at (prev + 1, 9) to (start + 0, 10)
52+
= ((c2 + c3) + c4)
53+
- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
54+
- MCDCDecision { bitmap_idx: 0, conditions_num: 3 } at (prev + 0, 13) to (start + 0, 24)
55+
- MCDCBranch { true: Counter(1), false: Expression(6, Sub), condition_id: 1, true_next_id: 3, false_next_id: 2 } at (prev + 0, 13) to (start + 0, 14)
56+
true = c1
57+
false = (c0 - c1)
58+
- Code(Counter(1)) at (prev + 0, 18) to (start + 0, 19)
59+
- MCDCBranch { true: Counter(2), false: Expression(5, Sub), condition_id: 3, true_next_id: 0, false_next_id: 2 } at (prev + 0, 18) to (start + 0, 19)
60+
true = c2
61+
false = (c1 - c2)
62+
- Code(Expression(4, Add)) at (prev + 0, 23) to (start + 0, 24)
63+
= ((c1 - c2) + (c0 - c1))
64+
- MCDCBranch { true: Counter(3), false: Counter(4), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 23) to (start + 0, 24)
65+
true = c3
66+
false = c4
67+
- Code(Expression(0, Add)) at (prev + 1, 5) to (start + 1, 2)
68+
= ((c2 + c3) + c4)
69+
70+
Function name: mcdc_non_control_flow::assign_and
71+
Raw bytes (64): 0x[01, 01, 04, 07, 0e, 09, 0d, 01, 05, 01, 05, 08, 01, 0c, 01, 00, 21, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 00, 02, 00, 0d, 00, 13, 30, 05, 0e, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 0d, 02, 00, 00, 00, 12, 00, 13, 03, 01, 05, 01, 02]
72+
Number of files: 1
73+
- file 0 => global file 1
74+
Number of expressions: 4
75+
- expression 0 operands: lhs = Expression(1, Add), rhs = Expression(3, Sub)
76+
- expression 1 operands: lhs = Counter(2), rhs = Counter(3)
77+
- expression 2 operands: lhs = Counter(0), rhs = Counter(1)
78+
- expression 3 operands: lhs = Counter(0), rhs = Counter(1)
79+
Number of file 0 mappings: 8
80+
- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 33)
81+
- Code(Expression(0, Add)) at (prev + 1, 9) to (start + 0, 10)
82+
= ((c2 + c3) + (c0 - c1))
83+
- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
84+
- MCDCDecision { bitmap_idx: 0, conditions_num: 2 } at (prev + 0, 13) to (start + 0, 19)
85+
- MCDCBranch { true: Counter(1), false: Expression(3, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14)
86+
true = c1
87+
false = (c0 - c1)
88+
- Code(Counter(1)) at (prev + 0, 18) to (start + 0, 19)
89+
- MCDCBranch { true: Counter(2), false: Counter(3), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 18) to (start + 0, 19)
90+
true = c2
91+
false = c3
92+
- Code(Expression(0, Add)) at (prev + 1, 5) to (start + 1, 2)
93+
= ((c2 + c3) + (c0 - c1))
94+
95+
Function name: mcdc_non_control_flow::assign_or
96+
Raw bytes (64): 0x[01, 01, 04, 07, 0d, 05, 09, 01, 05, 01, 05, 08, 01, 11, 01, 00, 20, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 00, 02, 00, 0d, 00, 13, 30, 05, 0e, 01, 00, 02, 00, 0d, 00, 0e, 0e, 00, 12, 00, 13, 30, 09, 0d, 02, 00, 00, 00, 12, 00, 13, 03, 01, 05, 01, 02]
97+
Number of files: 1
98+
- file 0 => global file 1
99+
Number of expressions: 4
100+
- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(3)
101+
- expression 1 operands: lhs = Counter(1), rhs = Counter(2)
102+
- expression 2 operands: lhs = Counter(0), rhs = Counter(1)
103+
- expression 3 operands: lhs = Counter(0), rhs = Counter(1)
104+
Number of file 0 mappings: 8
105+
- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 32)
106+
- Code(Expression(0, Add)) at (prev + 1, 9) to (start + 0, 10)
107+
= ((c1 + c2) + c3)
108+
- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
109+
- MCDCDecision { bitmap_idx: 0, conditions_num: 2 } at (prev + 0, 13) to (start + 0, 19)
110+
- MCDCBranch { true: Counter(1), false: Expression(3, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 13) to (start + 0, 14)
111+
true = c1
112+
false = (c0 - c1)
113+
- Code(Expression(3, Sub)) at (prev + 0, 18) to (start + 0, 19)
114+
= (c0 - c1)
115+
- MCDCBranch { true: Counter(2), false: Counter(3), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 18) to (start + 0, 19)
116+
true = c2
117+
false = c3
118+
- Code(Expression(0, Add)) at (prev + 1, 5) to (start + 1, 2)
119+
= ((c1 + c2) + c3)
120+
121+
Function name: mcdc_non_control_flow::foo
122+
Raw bytes (9): 0x[01, 01, 00, 01, 01, 25, 01, 02, 02]
123+
Number of files: 1
124+
- file 0 => global file 1
125+
Number of expressions: 0
126+
Number of file 0 mappings: 1
127+
- Code(Counter(0)) at (prev + 37, 1) to (start + 2, 2)
128+
129+
Function name: mcdc_non_control_flow::func_call
130+
Raw bytes (52): 0x[01, 01, 03, 01, 05, 0b, 02, 09, 0d, 06, 01, 29, 01, 01, 0a, 28, 00, 02, 01, 09, 00, 0f, 30, 05, 02, 01, 02, 00, 00, 09, 00, 0a, 05, 00, 0e, 00, 0f, 30, 09, 0d, 02, 00, 00, 00, 0e, 00, 0f, 07, 01, 01, 00, 02]
131+
Number of files: 1
132+
- file 0 => global file 1
133+
Number of expressions: 3
134+
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
135+
- expression 1 operands: lhs = Expression(2, Add), rhs = Expression(0, Sub)
136+
- expression 2 operands: lhs = Counter(2), rhs = Counter(3)
137+
Number of file 0 mappings: 6
138+
- Code(Counter(0)) at (prev + 41, 1) to (start + 1, 10)
139+
- MCDCDecision { bitmap_idx: 0, conditions_num: 2 } at (prev + 1, 9) to (start + 0, 15)
140+
- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 9) to (start + 0, 10)
141+
true = c1
142+
false = (c0 - c1)
143+
- Code(Counter(1)) at (prev + 0, 14) to (start + 0, 15)
144+
- MCDCBranch { true: Counter(2), false: Counter(3), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 14) to (start + 0, 15)
145+
true = c2
146+
false = c3
147+
- Code(Expression(1, Add)) at (prev + 1, 1) to (start + 0, 2)
148+
= ((c2 + c3) + (c0 - c1))
149+
150+
Function name: mcdc_non_control_flow::right_comb_tree
151+
Raw bytes (139): 0x[01, 01, 13, 07, 1a, 0b, 19, 0f, 15, 13, 11, 09, 0d, 01, 05, 01, 05, 05, 19, 05, 19, 4a, 15, 05, 19, 4a, 15, 05, 19, 46, 11, 4a, 15, 05, 19, 46, 11, 4a, 15, 05, 19, 0e, 01, 20, 01, 00, 41, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 00, 05, 00, 0d, 00, 2a, 30, 05, 1a, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 13, 00, 14, 30, 4a, 19, 02, 03, 00, 00, 13, 00, 14, 4a, 00, 19, 00, 1a, 30, 46, 15, 03, 04, 00, 00, 19, 00, 1a, 46, 00, 1f, 00, 20, 30, 42, 11, 04, 05, 00, 00, 1f, 00, 20, 42, 00, 24, 00, 27, 30, 09, 0d, 05, 00, 00, 00, 24, 00, 27, 03, 01, 05, 01, 02]
152+
Number of files: 1
153+
- file 0 => global file 1
154+
Number of expressions: 19
155+
- expression 0 operands: lhs = Expression(1, Add), rhs = Expression(6, Sub)
156+
- expression 1 operands: lhs = Expression(2, Add), rhs = Counter(6)
157+
- expression 2 operands: lhs = Expression(3, Add), rhs = Counter(5)
158+
- expression 3 operands: lhs = Expression(4, Add), rhs = Counter(4)
159+
- expression 4 operands: lhs = Counter(2), rhs = Counter(3)
160+
- expression 5 operands: lhs = Counter(0), rhs = Counter(1)
161+
- expression 6 operands: lhs = Counter(0), rhs = Counter(1)
162+
- expression 7 operands: lhs = Counter(1), rhs = Counter(6)
163+
- expression 8 operands: lhs = Counter(1), rhs = Counter(6)
164+
- expression 9 operands: lhs = Expression(18, Sub), rhs = Counter(5)
165+
- expression 10 operands: lhs = Counter(1), rhs = Counter(6)
166+
- expression 11 operands: lhs = Expression(18, Sub), rhs = Counter(5)
167+
- expression 12 operands: lhs = Counter(1), rhs = Counter(6)
168+
- expression 13 operands: lhs = Expression(17, Sub), rhs = Counter(4)
169+
- expression 14 operands: lhs = Expression(18, Sub), rhs = Counter(5)
170+
- expression 15 operands: lhs = Counter(1), rhs = Counter(6)
171+
- expression 16 operands: lhs = Expression(17, Sub), rhs = Counter(4)
172+
- expression 17 operands: lhs = Expression(18, Sub), rhs = Counter(5)
173+
- expression 18 operands: lhs = Counter(1), rhs = Counter(6)
174+
Number of file 0 mappings: 14
175+
- Code(Counter(0)) at (prev + 32, 1) to (start + 0, 65)
176+
- Code(Expression(0, Add)) at (prev + 1, 9) to (start + 0, 10)
177+
= (((((c2 + c3) + c4) + c5) + c6) + (c0 - c1))
178+
- Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
179+
- MCDCDecision { bitmap_idx: 0, conditions_num: 5 } at (prev + 0, 13) to (start + 0, 42)
180+
- MCDCBranch { true: Counter(1), false: Expression(6, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 13) to (start + 0, 14)
181+
true = c1
182+
false = (c0 - c1)
183+
- Code(Counter(1)) at (prev + 0, 19) to (start + 0, 20)
184+
- MCDCBranch { true: Expression(18, Sub), false: Counter(6), condition_id: 2, true_next_id: 3, false_next_id: 0 } at (prev + 0, 19) to (start + 0, 20)
185+
true = (c1 - c6)
186+
false = c6
187+
- Code(Expression(18, Sub)) at (prev + 0, 25) to (start + 0, 26)
188+
= (c1 - c6)
189+
- MCDCBranch { true: Expression(17, Sub), false: Counter(5), condition_id: 3, true_next_id: 4, false_next_id: 0 } at (prev + 0, 25) to (start + 0, 26)
190+
true = ((c1 - c6) - c5)
191+
false = c5
192+
- Code(Expression(17, Sub)) at (prev + 0, 31) to (start + 0, 32)
193+
= ((c1 - c6) - c5)
194+
- MCDCBranch { true: Expression(16, Sub), false: Counter(4), condition_id: 4, true_next_id: 5, false_next_id: 0 } at (prev + 0, 31) to (start + 0, 32)
195+
true = (((c1 - c6) - c5) - c4)
196+
false = c4
197+
- Code(Expression(16, Sub)) at (prev + 0, 36) to (start + 0, 39)
198+
= (((c1 - c6) - c5) - c4)
199+
- MCDCBranch { true: Counter(2), false: Counter(3), condition_id: 5, true_next_id: 0, false_next_id: 0 } at (prev + 0, 36) to (start + 0, 39)
200+
true = c2
201+
false = c3
202+
- Code(Expression(0, Add)) at (prev + 1, 5) to (start + 1, 2)
203+
= (((((c2 + c3) + c4) + c5) + c6) + (c0 - c1))
204+

0 commit comments

Comments
 (0)