@@ -2,8 +2,9 @@ use std::collections::BTreeSet;
22
33use rustc_data_structures:: graph:: DirectedGraph ;
44use rustc_index:: bit_set:: BitSet ;
5+ use rustc_index:: IndexVec ;
56use rustc_middle:: mir:: coverage:: {
6- BlockMarkerId , BranchSpan , ConditionInfo , CoverageKind , MCDCBranchSpan , MCDCDecisionSpan ,
7+ BlockMarkerId , BranchSpan , ConditionInfo , CoverageKind , MCDCBranchSpan ,
78} ;
89use rustc_middle:: mir:: { self , BasicBlock , StatementKind } ;
910use rustc_span:: Span ;
@@ -13,7 +14,6 @@ use crate::coverage::spans::{
1314 extract_refined_covspans, unexpand_into_body_span_with_visible_macro,
1415} ;
1516use crate :: coverage:: ExtractedHirInfo ;
16- use rustc_index:: IndexVec ;
1717
1818#[ derive( Clone , Debug ) ]
1919pub ( super ) enum BcbMappingKind {
@@ -32,13 +32,6 @@ pub(super) enum BcbMappingKind {
3232 condition_info : Option < ConditionInfo > ,
3333 decision_depth : u16 ,
3434 } ,
35- /// Associates a mcdc decision with its join BCB.
36- MCDCDecision {
37- end_bcbs : BTreeSet < BasicCoverageBlock > ,
38- bitmap_idx : u32 ,
39- conditions_num : u16 ,
40- decision_depth : u16 ,
41- } ,
4235}
4336
4437#[ derive( Debug ) ]
@@ -57,11 +50,22 @@ pub(super) struct BcbBranchPair {
5750 pub ( super ) false_bcb : BasicCoverageBlock ,
5851}
5952
53+ /// Associates an MC/DC decision with its join BCBs.
54+ #[ derive( Debug ) ]
55+ pub ( super ) struct MCDCDecision {
56+ pub ( super ) span : Span ,
57+ pub ( super ) end_bcbs : BTreeSet < BasicCoverageBlock > ,
58+ pub ( super ) bitmap_idx : u32 ,
59+ pub ( super ) conditions_num : u16 ,
60+ pub ( super ) decision_depth : u16 ,
61+ }
62+
6063pub ( super ) struct CoverageSpans {
6164 bcb_has_mappings : BitSet < BasicCoverageBlock > ,
6265 pub ( super ) mappings : Vec < BcbMapping > ,
6366 pub ( super ) branch_pairs : Vec < BcbBranchPair > ,
6467 test_vector_bitmap_bytes : u32 ,
68+ pub ( super ) mcdc_decisions : Vec < MCDCDecision > ,
6569}
6670
6771impl CoverageSpans {
@@ -85,6 +89,7 @@ pub(super) fn generate_coverage_spans(
8589) -> Option < CoverageSpans > {
8690 let mut mappings = vec ! [ ] ;
8791 let mut branch_pairs = vec ! [ ] ;
92+ let mut mcdc_decisions = vec ! [ ] ;
8893
8994 if hir_info. is_async_fn {
9095 // An async function desugars into a function that returns a future,
@@ -99,10 +104,15 @@ pub(super) fn generate_coverage_spans(
99104
100105 branch_pairs. extend ( extract_branch_pairs ( mir_body, hir_info, basic_coverage_blocks) ) ;
101106
102- mappings. extend ( extract_mcdc_mappings ( mir_body, hir_info. body_span , basic_coverage_blocks) ) ;
107+ mappings. extend ( extract_mcdc_mappings (
108+ mir_body,
109+ hir_info. body_span ,
110+ basic_coverage_blocks,
111+ & mut mcdc_decisions,
112+ ) ) ;
103113 }
104114
105- if mappings. is_empty ( ) && branch_pairs. is_empty ( ) {
115+ if mappings. is_empty ( ) && branch_pairs. is_empty ( ) && mcdc_decisions . is_empty ( ) {
106116 return None ;
107117 }
108118
@@ -111,29 +121,37 @@ pub(super) fn generate_coverage_spans(
111121 let mut insert = |bcb| {
112122 bcb_has_mappings. insert ( bcb) ;
113123 } ;
114- let mut test_vector_bitmap_bytes = 0 ;
124+
115125 for BcbMapping { kind, span : _ } in & mappings {
116126 match * kind {
117127 BcbMappingKind :: Code ( bcb) => insert ( bcb) ,
118128 BcbMappingKind :: MCDCBranch { true_bcb, false_bcb, .. } => {
119129 insert ( true_bcb) ;
120130 insert ( false_bcb) ;
121131 }
122- BcbMappingKind :: MCDCDecision { bitmap_idx, conditions_num, .. } => {
123- // `bcb_has_mappings` is used for inject coverage counters
124- // but they are not needed for decision BCBs.
125- // While the length of test vector bitmap should be calculated here.
126- test_vector_bitmap_bytes = test_vector_bitmap_bytes
127- . max ( bitmap_idx + ( 1_u32 << conditions_num as u32 ) . div_ceil ( 8 ) ) ;
128- }
129132 }
130133 }
131134 for & BcbBranchPair { true_bcb, false_bcb, .. } in & branch_pairs {
132135 insert ( true_bcb) ;
133136 insert ( false_bcb) ;
134137 }
135138
136- Some ( CoverageSpans { bcb_has_mappings, mappings, branch_pairs, test_vector_bitmap_bytes } )
139+ // Determine the length of the test vector bitmap.
140+ let test_vector_bitmap_bytes = mcdc_decisions
141+ . iter ( )
142+ . map ( |& MCDCDecision { bitmap_idx, conditions_num, .. } | {
143+ bitmap_idx + ( 1_u32 << u32:: from ( conditions_num) ) . div_ceil ( 8 )
144+ } )
145+ . max ( )
146+ . unwrap_or ( 0 ) ;
147+
148+ Some ( CoverageSpans {
149+ bcb_has_mappings,
150+ mappings,
151+ branch_pairs,
152+ test_vector_bitmap_bytes,
153+ mcdc_decisions,
154+ } )
137155}
138156
139157fn resolve_block_markers (
@@ -199,6 +217,7 @@ pub(super) fn extract_mcdc_mappings(
199217 mir_body : & mir:: Body < ' _ > ,
200218 body_span : Span ,
201219 basic_coverage_blocks : & CoverageGraph ,
220+ mcdc_decisions : & mut impl Extend < MCDCDecision > ,
202221) -> Vec < BcbMapping > {
203222 let Some ( branch_info) = mir_body. coverage_branch_info . as_deref ( ) else {
204223 return vec ! [ ] ;
@@ -245,31 +264,30 @@ pub(super) fn extract_mcdc_mappings(
245264
246265 let mut next_bitmap_idx = 0 ;
247266
248- let decision_filter_map = |decision : & MCDCDecisionSpan | {
249- let ( span, _) = unexpand_into_body_span_with_visible_macro ( decision. span , body_span) ?;
267+ mcdc_decisions. extend ( branch_info. mcdc_decision_spans . iter ( ) . filter_map (
268+ |decision : & mir:: coverage:: MCDCDecisionSpan | {
269+ let ( span, _) = unexpand_into_body_span_with_visible_macro ( decision. span , body_span) ?;
250270
251- let end_bcbs = decision
252- . end_markers
253- . iter ( )
254- . map ( |& marker| bcb_from_marker ( marker) )
255- . collect :: < Option < _ > > ( ) ?;
271+ let end_bcbs = decision
272+ . end_markers
273+ . iter ( )
274+ . map ( |& marker| bcb_from_marker ( marker) )
275+ . collect :: < Option < _ > > ( ) ?;
256276
257- let bitmap_idx = next_bitmap_idx;
258- next_bitmap_idx += ( 1_u32 << decision. conditions_num ) . div_ceil ( 8 ) ;
277+ let bitmap_idx = next_bitmap_idx;
278+ next_bitmap_idx += ( 1_u32 << decision. conditions_num ) . div_ceil ( 8 ) ;
259279
260- Some ( BcbMapping {
261- kind : BcbMappingKind :: MCDCDecision {
280+ Some ( MCDCDecision {
281+ span ,
262282 end_bcbs,
263283 bitmap_idx,
264284 conditions_num : decision. conditions_num as u16 ,
265285 decision_depth : decision. decision_depth ,
266- } ,
267- span,
268- } )
269- } ;
286+ } )
287+ } ,
288+ ) ) ;
270289
271290 std:: iter:: empty ( )
272291 . chain ( branch_info. mcdc_branch_spans . iter ( ) . filter_map ( mcdc_branch_filter_map) )
273- . chain ( branch_info. mcdc_decision_spans . iter ( ) . filter_map ( decision_filter_map) )
274292 . collect :: < Vec < _ > > ( )
275293}
0 commit comments