Skip to content

Commit 7d1d52e

Browse files
author
zhuyunxing
committed
coverage. Fix panic when generating mcdc code for inlined functions
1 parent 722aea5 commit 7d1d52e

File tree

5 files changed

+92
-1
lines changed

5 files changed

+92
-1
lines changed

compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs

+9
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ impl<'ll, 'tcx> CrateCoverageContext<'ll, 'tcx> {
4949
self.function_coverage_map.replace(FxIndexMap::default())
5050
}
5151

52+
fn is_initialized_for(&self, instance: &Instance<'tcx>) -> bool {
53+
self.mcdc_condition_bitmap_map.borrow().contains_key(instance)
54+
}
55+
5256
/// LLVM use a temp value to record evaluated mcdc test vector of each decision, which is called condition bitmap.
5357
/// In order to handle nested decisions, several condition bitmaps can be
5458
/// allocated for a function body.
@@ -93,6 +97,11 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
9397

9498
impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
9599
fn init_coverage(&mut self, instance: Instance<'tcx>) {
100+
// Already initialized the context.
101+
if !self.coverage_context().is_some_and(|ctx| !ctx.is_initialized_for(&instance)) {
102+
return;
103+
}
104+
96105
let Some(function_coverage_info) =
97106
self.tcx.instance_mir(instance.def).function_coverage_info.as_deref()
98107
else {

compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
99
pub fn codegen_coverage(&self, bx: &mut Bx, kind: &CoverageKind, scope: SourceScope) {
1010
// Determine the instance that coverage data was originally generated for.
1111
let instance = if let Some(inlined) = scope.inlined_instance(&self.mir.source_scopes) {
12-
self.monomorphize(inlined)
12+
let primary_instance = self.monomorphize(inlined);
13+
// Coverage context of the inlined instance may not be initialized before.
14+
bx.init_coverage(primary_instance);
15+
primary_instance
1316
} else {
1417
self.instance
1518
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
Function name: inlined_expressions::inlined_instance
2+
Raw bytes (52): 0x[01, 01, 03, 01, 05, 0b, 02, 09, 0d, 06, 01, 08, 01, 01, 06, 28, 00, 02, 01, 05, 00, 0b, 30, 05, 02, 01, 02, 00, 00, 05, 00, 06, 05, 00, 0a, 00, 0b, 30, 09, 0d, 02, 00, 00, 00, 0a, 00, 0b, 07, 01, 01, 00, 02]
3+
Number of files: 1
4+
- file 0 => global file 1
5+
Number of expressions: 3
6+
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
7+
- expression 1 operands: lhs = Expression(2, Add), rhs = Expression(0, Sub)
8+
- expression 2 operands: lhs = Counter(2), rhs = Counter(3)
9+
Number of file 0 mappings: 6
10+
- Code(Counter(0)) at (prev + 8, 1) to (start + 1, 6)
11+
- MCDCDecision { bitmap_idx: 0, conditions_num: 2 } at (prev + 1, 5) to (start + 0, 11)
12+
- MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 5) to (start + 0, 6)
13+
true = c1
14+
false = (c0 - c1)
15+
- Code(Counter(1)) at (prev + 0, 10) to (start + 0, 11)
16+
- MCDCBranch { true: Counter(2), false: Counter(3), condition_id: 2, true_next_id: 0, false_next_id: 0 } at (prev + 0, 10) to (start + 0, 11)
17+
true = c2
18+
false = c3
19+
- Code(Expression(1, Add)) at (prev + 1, 1) to (start + 0, 2)
20+
= ((c2 + c3) + (c0 - c1))
21+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
LL| |#![feature(coverage_attribute)]
2+
LL| |//@ edition: 2021
3+
LL| |//@ min-llvm-version: 18
4+
LL| |//@ compile-flags: -Zcoverage-options=mcdc -Cinline-threshold=0
5+
LL| |//@ llvm-cov-flags: --show-branches=count --show-mcdc
6+
LL| |
7+
LL| |#[inline(always)]
8+
LL| 3|fn inlined_instance(a: bool, b: bool) -> bool {
9+
LL| 3| a && b
10+
^2
11+
------------------
12+
| Branch (LL:5): [True: 2, False: 1]
13+
| Branch (LL:10): [True: 1, False: 1]
14+
------------------
15+
|---> MC/DC Decision Region (LL:5) to (LL:11)
16+
|
17+
| Number of Conditions: 2
18+
| Condition C1 --> (LL:5)
19+
| Condition C2 --> (LL:10)
20+
|
21+
| Executed MC/DC Test Vectors:
22+
|
23+
| C1, C2 Result
24+
| 1 { F, - = F }
25+
| 2 { T, F = F }
26+
| 3 { T, T = T }
27+
|
28+
| C1-Pair: covered: (1,3)
29+
| C2-Pair: covered: (2,3)
30+
| MC/DC Coverage for Decision: 100.00%
31+
|
32+
------------------
33+
LL| 3|}
34+
LL| |
35+
LL| |#[coverage(off)]
36+
LL| |fn main() {
37+
LL| | let _ = inlined_instance(true, false);
38+
LL| | let _ = inlined_instance(false, true);
39+
LL| | let _ = inlined_instance(true, true);
40+
LL| |}
41+
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#![feature(coverage_attribute)]
2+
//@ edition: 2021
3+
//@ min-llvm-version: 18
4+
//@ compile-flags: -Zcoverage-options=mcdc -Cinline-threshold=0
5+
//@ llvm-cov-flags: --show-branches=count --show-mcdc
6+
7+
#[inline(always)]
8+
fn inlined_instance(a: bool, b: bool) -> bool {
9+
a && b
10+
}
11+
12+
#[coverage(off)]
13+
fn main() {
14+
let _ = inlined_instance(true, false);
15+
let _ = inlined_instance(false, true);
16+
let _ = inlined_instance(true, true);
17+
}

0 commit comments

Comments
 (0)