Skip to content

Commit d7a46c6

Browse files
author
zhuyunxing
committed
coverage. Fix DropGlue instances might cause rustc panic when mcdc is enabled
1 parent 51e6096 commit d7a46c6

File tree

1 file changed

+27
-3
lines changed
  • compiler/rustc_codegen_llvm/src/coverageinfo

1 file changed

+27
-3
lines changed

compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs

+27-3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
99
use rustc_llvm::RustString;
1010
use rustc_middle::bug;
1111
use rustc_middle::mir::coverage::CoverageKind;
12+
use rustc_middle::mir::{Statement, StatementKind};
1213
use rustc_middle::ty::layout::HasTyCtxt;
1314
use rustc_middle::ty::Instance;
1415
use rustc_target::abi::{Align, Size};
@@ -92,16 +93,39 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
9293

9394
impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
9495
fn init_coverage(&mut self, instance: Instance<'tcx>) {
95-
let Some(function_coverage_info) =
96-
self.tcx.instance_mir(instance.def).function_coverage_info.as_deref()
97-
else {
96+
let mir_body = self.tcx.instance_mir(instance.def);
97+
98+
let Some(function_coverage_info) = mir_body.function_coverage_info.as_deref() else {
9899
return;
99100
};
100101

101102
// If there are no MC/DC bitmaps to set up, return immediately.
102103
if function_coverage_info.mcdc_bitmap_bits == 0 {
103104
return;
104105
}
106+
let is_mcdc_instrument = |statement: &Statement<'_>| {
107+
let StatementKind::Coverage(coverage_kind) = &statement.kind else {
108+
return false;
109+
};
110+
matches!(
111+
coverage_kind,
112+
CoverageKind::TestVectorBitmapUpdate { .. }
113+
| CoverageKind::CondBitmapUpdate { .. }
114+
| CoverageKind::CondBitmapReset { .. }
115+
)
116+
};
117+
// Mir bodies of instances like `DropGlue` might be cloned from other instances' and removed some basic blocks.
118+
// Such instances likely have same `function_coverage_info` as primary instances but have no coverage statements.
119+
// No need to initialize mcdc parameters for this kind of instances.
120+
if !mir_body
121+
.basic_blocks
122+
.iter()
123+
.map(|bb| bb.statements.iter())
124+
.flatten()
125+
.any(is_mcdc_instrument)
126+
{
127+
return;
128+
}
105129

106130
let fn_name = self.get_pgo_func_name_var(instance);
107131
let hash = self.const_u64(function_coverage_info.function_source_hash);

0 commit comments

Comments
 (0)