Skip to content

Commit ac71f67

Browse files
author
zhuyunxing
committed
coverage. Implement branch coverage in mcdc for pattern match
1 parent 9cf10bc commit ac71f67

File tree

9 files changed

+539
-77
lines changed

9 files changed

+539
-77
lines changed

compiler/rustc_middle/src/mir/coverage.rs

+32-2
Original file line numberDiff line numberDiff line change
@@ -280,8 +280,7 @@ pub struct BranchInfo {
280280
/// data structures without having to scan the entire body first.
281281
pub num_block_markers: usize,
282282
pub branch_spans: Vec<BranchSpan>,
283-
pub mcdc_branch_spans: Vec<MCDCBranchSpan>,
284-
pub mcdc_decision_spans: Vec<MCDCDecisionSpan>,
283+
pub mcdc_info: Option<MCDCBranchInfo>,
285284
}
286285

287286
#[derive(Clone, Debug)]
@@ -321,6 +320,20 @@ pub struct MCDCBranchSpan {
321320
pub false_marker: BlockMarkerId,
322321
}
323322

323+
#[derive(Clone, Debug)]
324+
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
325+
pub struct MCDCMatchArmSpan {
326+
pub span: Span,
327+
pub condition_info: Option<ConditionInfo>,
328+
// Mark the blocks which test the pattern.
329+
pub test_markers: Vec<BlockMarkerId>,
330+
// The blocks switched into if this pattern was matched.
331+
pub true_markers: Vec<BlockMarkerId>,
332+
// The blocks of `true_markers` of the prior bindings.
333+
// Eg. in `A | B` pattern A is prior to pattern B.
334+
pub prior_binding_markers: Vec<BlockMarkerId>,
335+
}
336+
324337
#[derive(Copy, Clone, Debug)]
325338
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
326339
pub struct DecisionInfo {
@@ -335,3 +348,20 @@ pub struct MCDCDecisionSpan {
335348
pub conditions_num: usize,
336349
pub end_markers: Vec<BlockMarkerId>,
337350
}
351+
352+
/// Branch information recorded during THIR-to-MIR lowering, and stored in MIR.
353+
#[derive(Clone, Debug)]
354+
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
355+
pub struct MCDCBranchInfo {
356+
pub branch_spans: Vec<MCDCBranchSpan>,
357+
pub match_arm_spans: Vec<MCDCMatchArmSpan>,
358+
pub decision_spans: Vec<MCDCDecisionSpan>,
359+
}
360+
361+
impl MCDCBranchInfo {
362+
pub fn calc_bitmap_bytes(&self) -> u32 {
363+
self.decision_spans
364+
.iter()
365+
.fold(0, |acc, decision| acc + (1_u32 << decision.conditions_num).div_ceil(8))
366+
}
367+
}

compiler/rustc_middle/src/mir/pretty.rs

+39-17
Original file line numberDiff line numberDiff line change
@@ -475,35 +475,57 @@ fn write_coverage_branch_info(
475475
branch_info: &coverage::BranchInfo,
476476
w: &mut dyn io::Write,
477477
) -> io::Result<()> {
478-
let coverage::BranchInfo { branch_spans, mcdc_branch_spans, mcdc_decision_spans, .. } =
479-
branch_info;
478+
let coverage::BranchInfo { branch_spans, mcdc_info, .. } = branch_info;
480479

480+
let mut printed = false;
481481
for coverage::BranchSpan { span, true_marker, false_marker } in branch_spans {
482482
writeln!(
483483
w,
484484
"{INDENT}coverage branch {{ true: {true_marker:?}, false: {false_marker:?} }} => {span:?}",
485485
)?;
486486
}
487487

488-
for coverage::MCDCBranchSpan { span, condition_info, true_marker, false_marker } in
489-
mcdc_branch_spans
488+
printed |= !branch_spans.is_empty();
489+
490+
if let Some(coverage::MCDCBranchInfo { branch_spans, decision_spans, match_arm_spans }) =
491+
mcdc_info.as_ref()
490492
{
491-
writeln!(
492-
w,
493-
"{INDENT}coverage mcdc branch {{ condition_id: {:?}, true: {true_marker:?}, false: {false_marker:?} }} => {span:?}",
494-
condition_info.map(|info| info.condition_id)
495-
)?;
496-
}
493+
for coverage::MCDCBranchSpan { span, condition_info, true_marker, false_marker } in
494+
branch_spans
495+
{
496+
writeln!(
497+
w,
498+
"{INDENT}coverage mcdc branch {{ condition_id: {:?}, true: {true_marker:?}, false: {false_marker:?} }} => {span:?}",
499+
condition_info.map(|info| info.condition_id)
500+
)?;
501+
}
497502

498-
for coverage::MCDCDecisionSpan { span, conditions_num, end_markers } in mcdc_decision_spans {
499-
writeln!(
500-
w,
501-
"{INDENT}coverage mcdc decision {{ conditions_num: {conditions_num:?}, end: {end_markers:?} }} => {span:?}"
502-
)?;
503+
for coverage::MCDCMatchArmSpan {
504+
span,
505+
condition_info,
506+
test_markers,
507+
true_markers,
508+
prior_binding_markers,
509+
} in match_arm_spans
510+
{
511+
writeln!(
512+
w,
513+
"{INDENT}coverage mcdc match arm {{ condition_id: {:?}, test: {test_markers:?}, true: {true_markers:?}, prior: {prior_binding_markers:?} }} => {span:?}",
514+
condition_info.map(|info| info.condition_id)
515+
)?;
516+
}
517+
518+
for coverage::MCDCDecisionSpan { span, conditions_num, end_markers } in decision_spans {
519+
writeln!(
520+
w,
521+
"{INDENT}coverage mcdc decision {{ conditions_num: {conditions_num:?}, end: {end_markers:?} }} => {span:?}"
522+
)?;
523+
}
524+
printed |=
525+
!branch_spans.is_empty() || !decision_spans.is_empty() || !match_arm_spans.is_empty();
503526
}
504527

505-
if !branch_spans.is_empty() || !mcdc_branch_spans.is_empty() || !mcdc_decision_spans.is_empty()
506-
{
528+
if printed {
507529
writeln!(w)?;
508530
}
509531

0 commit comments

Comments
 (0)