From 1135cd3e783d51ff5910cbff37b443d0acbd08e6 Mon Sep 17 00:00:00 2001 From: zhuyunxing Date: Mon, 8 Apr 2024 21:01:16 +1000 Subject: [PATCH] Add MC/DC support to coverage test tools --- src/tools/compiletest/src/runtest.rs | 13 ++++++++ src/tools/coverage-dump/src/covfun.rs | 46 +++++++++++++++++++++++++-- 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index bb8509fe41377..03580c0f14c3e 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -752,6 +752,19 @@ impl<'test> TestCx<'test> { Lazy::new(|| Regex::new(r"(?m:^)(?(?: \|)+ Branch \()[0-9]+:").unwrap()); let coverage = BRANCH_LINE_NUMBER_RE.replace_all(&coverage, "${prefix}LL:"); + // ` |---> MC/DC Decision Region (1:30) to (2:` => ` |---> MC/DC Decision Region (LL:30) to (LL:` + static MCDC_DECISION_LINE_NUMBER_RE: Lazy = Lazy::new(|| { + Regex::new(r"(?m:^)(?(?: \|)+---> MC/DC Decision Region \()[0-9]+:(?[0-9]+\) to \()[0-9]+:").unwrap() + }); + let coverage = + MCDC_DECISION_LINE_NUMBER_RE.replace_all(&coverage, "${prefix}LL:${middle}LL:"); + + // ` | Condition C1 --> (1:` => ` | Condition C1 --> (LL:` + static MCDC_CONDITION_LINE_NUMBER_RE: Lazy = Lazy::new(|| { + Regex::new(r"(?m:^)(?(?: \|)+ Condition C[0-9]+ --> \()[0-9]+:").unwrap() + }); + let coverage = MCDC_CONDITION_LINE_NUMBER_RE.replace_all(&coverage, "${prefix}LL:"); + coverage.into_owned() } diff --git a/src/tools/coverage-dump/src/covfun.rs b/src/tools/coverage-dump/src/covfun.rs index 49e3a6ed58383..b308c8de14fe3 100644 --- a/src/tools/coverage-dump/src/covfun.rs +++ b/src/tools/coverage-dump/src/covfun.rs @@ -70,7 +70,8 @@ pub(crate) fn dump_covfun_mappings( } // If the mapping is a branch region, print both of its arms // in resolved form (even if they aren't expressions). - MappingKind::Branch { r#true, r#false } => { + MappingKind::Branch { r#true, r#false } + | MappingKind::MCDCBranch { r#true, r#false, .. } => { println!(" true = {}", expression_resolver.format_term(r#true)); println!(" false = {}", expression_resolver.format_term(r#false)); } @@ -164,6 +165,26 @@ impl<'a> Parser<'a> { let r#false = self.read_simple_term()?; Ok(MappingKind::Branch { r#true, r#false }) } + 5 => { + let bitmap_idx = self.read_uleb128_u32()?; + let conditions_num = self.read_uleb128_u32()?; + Ok(MappingKind::MCDCDecision { bitmap_idx, conditions_num }) + } + 6 => { + let r#true = self.read_simple_term()?; + let r#false = self.read_simple_term()?; + let condition_id = self.read_uleb128_u32()?; + let true_next_id = self.read_uleb128_u32()?; + let false_next_id = self.read_uleb128_u32()?; + Ok(MappingKind::MCDCBranch { + r#true, + r#false, + condition_id, + true_next_id, + false_next_id, + }) + } + _ => Err(anyhow!("unknown mapping kind: {raw_mapping_kind:#x}")), } } @@ -224,7 +245,28 @@ enum MappingKind { // Using raw identifiers here makes the dump output a little bit nicer // (via the derived Debug), at the expense of making this tool's source // code a little bit uglier. - Branch { r#true: CovTerm, r#false: CovTerm }, + Branch { + r#true: CovTerm, + r#false: CovTerm, + }, + MCDCBranch { + r#true: CovTerm, + r#false: CovTerm, + // These attributes are printed in Debug but not used directly. + #[allow(dead_code)] + condition_id: u32, + #[allow(dead_code)] + true_next_id: u32, + #[allow(dead_code)] + false_next_id: u32, + }, + MCDCDecision { + // These attributes are printed in Debug but not used directly. + #[allow(dead_code)] + bitmap_idx: u32, + #[allow(dead_code)] + conditions_num: u32, + }, } struct MappingRegion {