@@ -4,7 +4,8 @@ use std::collections::VecDeque;
4
4
5
5
use rustc_data_structures:: fx:: FxHashMap ;
6
6
use rustc_middle:: mir:: coverage:: {
7
- BlockMarkerId , BranchSpan , ConditionId , ConditionInfo , CoverageKind , DecisionSpan ,
7
+ BlockMarkerId , BranchSpan , ConditionId , ConditionInfo , CoverageKind , MCDCBranchSpan ,
8
+ MCDCDecisionSpan ,
8
9
} ;
9
10
use rustc_middle:: mir:: { self , BasicBlock , UnOp } ;
10
11
use rustc_middle:: thir:: { ExprId , ExprKind , LogicalOp , Thir } ;
@@ -21,7 +22,8 @@ pub(crate) struct BranchInfoBuilder {
21
22
22
23
num_block_markers : usize ,
23
24
branch_spans : Vec < BranchSpan > ,
24
- decision_spans : Vec < DecisionSpan > ,
25
+ mcdc_branch_spans : Vec < MCDCBranchSpan > ,
26
+ mcdc_decision_spans : Vec < MCDCDecisionSpan > ,
25
27
mcdc_state : Option < MCDCState > ,
26
28
}
27
29
@@ -44,7 +46,8 @@ impl BranchInfoBuilder {
44
46
nots : FxHashMap :: default ( ) ,
45
47
num_block_markers : 0 ,
46
48
branch_spans : vec ! [ ] ,
47
- decision_spans : vec ! [ ] ,
49
+ mcdc_branch_spans : vec ! [ ] ,
50
+ mcdc_decision_spans : vec ! [ ] ,
48
51
mcdc_state : MCDCState :: new_if_enabled ( tcx) ,
49
52
} )
50
53
} else {
@@ -103,10 +106,8 @@ impl BranchInfoBuilder {
103
106
tcx : TyCtxt < ' _ > ,
104
107
true_marker : BlockMarkerId ,
105
108
false_marker : BlockMarkerId ,
106
- ) -> ConditionInfo {
107
- let Some ( mcdc_state) = self . mcdc_state . as_mut ( ) else {
108
- return ConditionInfo :: default ( ) ;
109
- } ;
109
+ ) -> Option < ConditionInfo > {
110
+ let mcdc_state = self . mcdc_state . as_mut ( ) ?;
110
111
let ( mut condition_info, decision_result) =
111
112
mcdc_state. take_condition ( true_marker, false_marker) ;
112
113
if let Some ( decision) = decision_result {
@@ -115,17 +116,22 @@ impl BranchInfoBuilder {
115
116
unreachable ! ( "Decision with no condition is not expected" ) ;
116
117
}
117
118
1 ..=MAX_CONDITIONS_NUM_IN_DECISION => {
118
- self . decision_spans . push ( decision) ;
119
+ self . mcdc_decision_spans . push ( decision) ;
119
120
}
120
121
_ => {
121
122
// Do not generate mcdc mappings and statements for decisions with too many conditions.
122
- for branch in
123
- self . branch_spans . iter_mut ( ) . rev ( ) . take ( decision. conditions_num - 1 )
124
- {
125
- branch. condition_info = ConditionInfo :: default ( ) ;
126
- }
123
+ let rebase_idx = self . mcdc_branch_spans . len ( ) - decision. conditions_num + 1 ;
124
+ let to_normal_branches = self . mcdc_branch_spans . split_off ( rebase_idx) ;
125
+ self . branch_spans . extend ( to_normal_branches. into_iter ( ) . map (
126
+ |MCDCBranchSpan { span, true_marker, false_marker, .. } | BranchSpan {
127
+ span,
128
+ true_marker,
129
+ false_marker,
130
+ } ,
131
+ ) ) ;
132
+
127
133
// ConditionInfo of this branch shall also be reset.
128
- condition_info = ConditionInfo :: default ( ) ;
134
+ condition_info = None ;
129
135
130
136
tcx. dcx ( ) . emit_warn ( MCDCExceedsConditionNumLimit {
131
137
span : decision. span ,
@@ -145,7 +151,14 @@ impl BranchInfoBuilder {
145
151
}
146
152
147
153
pub ( crate ) fn into_done ( self ) -> Option < Box < mir:: coverage:: BranchInfo > > {
148
- let Self { nots : _, num_block_markers, branch_spans, decision_spans, .. } = self ;
154
+ let Self {
155
+ nots : _,
156
+ num_block_markers,
157
+ branch_spans,
158
+ mcdc_branch_spans,
159
+ mcdc_decision_spans,
160
+ ..
161
+ } = self ;
149
162
150
163
if num_block_markers == 0 {
151
164
assert ! ( branch_spans. is_empty( ) ) ;
@@ -155,7 +168,8 @@ impl BranchInfoBuilder {
155
168
Some ( Box :: new ( mir:: coverage:: BranchInfo {
156
169
num_block_markers,
157
170
branch_spans,
158
- decision_spans,
171
+ mcdc_branch_spans,
172
+ mcdc_decision_spans,
159
173
} ) )
160
174
}
161
175
}
@@ -168,7 +182,7 @@ const MAX_CONDITIONS_NUM_IN_DECISION: usize = 6;
168
182
struct MCDCState {
169
183
/// To construct condition evaluation tree.
170
184
decision_stack : VecDeque < ConditionInfo > ,
171
- processing_decision : Option < DecisionSpan > ,
185
+ processing_decision : Option < MCDCDecisionSpan > ,
172
186
}
173
187
174
188
impl MCDCState {
@@ -224,10 +238,10 @@ impl MCDCState {
224
238
decision. span = decision. span . to ( span) ;
225
239
decision
226
240
}
227
- None => self . processing_decision . insert ( DecisionSpan {
241
+ None => self . processing_decision . insert ( MCDCDecisionSpan {
228
242
span,
229
243
conditions_num : 0 ,
230
- end_marker : vec ! [ ] ,
244
+ end_markers : vec ! [ ] ,
231
245
} ) ,
232
246
} ;
233
247
@@ -279,24 +293,24 @@ impl MCDCState {
279
293
& mut self ,
280
294
true_marker : BlockMarkerId ,
281
295
false_marker : BlockMarkerId ,
282
- ) -> ( ConditionInfo , Option < DecisionSpan > ) {
296
+ ) -> ( Option < ConditionInfo > , Option < MCDCDecisionSpan > ) {
283
297
let Some ( condition_info) = self . decision_stack . pop_back ( ) else {
284
- return ( ConditionInfo :: default ( ) , None ) ;
298
+ return ( None , None ) ;
285
299
} ;
286
300
let Some ( decision) = self . processing_decision . as_mut ( ) else {
287
301
bug ! ( "Processing decision should have been created before any conditions are taken" ) ;
288
302
} ;
289
303
if condition_info. true_next_id == ConditionId :: NONE {
290
- decision. end_marker . push ( true_marker) ;
304
+ decision. end_markers . push ( true_marker) ;
291
305
}
292
306
if condition_info. false_next_id == ConditionId :: NONE {
293
- decision. end_marker . push ( false_marker) ;
307
+ decision. end_markers . push ( false_marker) ;
294
308
}
295
309
296
310
if self . decision_stack . is_empty ( ) {
297
- ( condition_info, self . processing_decision . take ( ) )
311
+ ( Some ( condition_info) , self . processing_decision . take ( ) )
298
312
} else {
299
- ( condition_info, None )
313
+ ( Some ( condition_info) , None )
300
314
}
301
315
}
302
316
}
@@ -341,14 +355,22 @@ impl Builder<'_, '_> {
341
355
let true_marker = inject_branch_marker ( then_block) ;
342
356
let false_marker = inject_branch_marker ( else_block) ;
343
357
344
- let condition_info = branch_info. fetch_condition_info ( self . tcx , true_marker, false_marker) ;
345
-
346
- branch_info. branch_spans . push ( BranchSpan {
347
- span : source_info. span ,
348
- condition_info,
349
- true_marker,
350
- false_marker,
351
- } ) ;
358
+ if let Some ( condition_info) =
359
+ branch_info. fetch_condition_info ( self . tcx , true_marker, false_marker)
360
+ {
361
+ branch_info. mcdc_branch_spans . push ( MCDCBranchSpan {
362
+ span : source_info. span ,
363
+ condition_info,
364
+ true_marker,
365
+ false_marker,
366
+ } ) ;
367
+ } else {
368
+ branch_info. branch_spans . push ( BranchSpan {
369
+ span : source_info. span ,
370
+ true_marker,
371
+ false_marker,
372
+ } ) ;
373
+ }
352
374
}
353
375
354
376
pub ( crate ) fn visit_coverage_branch_operation ( & mut self , logical_op : LogicalOp , span : Span ) {
0 commit comments