@@ -70,22 +70,6 @@ struct ConstAnalysis<'a, 'tcx> {
70
70
param_env : ty:: ParamEnv < ' tcx > ,
71
71
}
72
72
73
- impl < ' tcx > ConstAnalysis < ' _ , ' tcx > {
74
- fn eval_discriminant (
75
- & self ,
76
- enum_ty : Ty < ' tcx > ,
77
- variant_index : VariantIdx ,
78
- ) -> Option < ScalarTy < ' tcx > > {
79
- if !enum_ty. is_enum ( ) {
80
- return None ;
81
- }
82
- let discr = enum_ty. discriminant_for_variant ( self . tcx , variant_index) ?;
83
- let discr_layout = self . tcx . layout_of ( self . param_env . and ( discr. ty ) ) . ok ( ) ?;
84
- let discr_value = Scalar :: try_from_uint ( discr. val , discr_layout. size ) ?;
85
- Some ( ScalarTy ( discr_value, discr. ty ) )
86
- }
87
- }
88
-
89
73
impl < ' tcx > ValueAnalysis < ' tcx > for ConstAnalysis < ' _ , ' tcx > {
90
74
type Value = FlatSet < ScalarTy < ' tcx > > ;
91
75
@@ -126,59 +110,55 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
126
110
// we must make sure that all `target as Variant#i` are `Top`.
127
111
state. flood ( target. as_ref ( ) , self . map ( ) ) ;
128
112
129
- if let Some ( target_idx) = self . map ( ) . find ( target. as_ref ( ) ) {
130
- let ( variant_target, variant_index) = match * * kind {
131
- AggregateKind :: Tuple | AggregateKind :: Closure ( ..) => {
132
- ( Some ( target_idx) , None )
133
- }
134
- AggregateKind :: Adt ( def_id, variant_index, ..) => {
135
- match self . tcx . def_kind ( def_id) {
136
- DefKind :: Struct => ( Some ( target_idx) , None ) ,
137
- DefKind :: Enum => (
138
- self . map . apply ( target_idx, TrackElem :: Variant ( variant_index) ) ,
139
- Some ( variant_index) ,
140
- ) ,
141
- _ => ( None , None ) ,
142
- }
143
- }
144
- _ => ( None , None ) ,
145
- } ;
146
- if let Some ( variant_target_idx) = variant_target {
147
- for ( field_index, operand) in operands. iter ( ) . enumerate ( ) {
148
- if let Some ( field) = self . map ( ) . apply (
149
- variant_target_idx,
150
- TrackElem :: Field ( FieldIdx :: from_usize ( field_index) ) ,
151
- ) {
152
- let result = self . handle_operand ( operand, state) ;
153
- state. insert_idx ( field, result, self . map ( ) ) ;
154
- }
113
+ let Some ( target_idx) = self . map ( ) . find ( target. as_ref ( ) ) else { return } ;
114
+
115
+ let ( variant_target, variant_index) = match * * kind {
116
+ AggregateKind :: Tuple | AggregateKind :: Closure ( ..) => ( Some ( target_idx) , None ) ,
117
+ AggregateKind :: Adt ( def_id, variant_index, ..) => {
118
+ match self . tcx . def_kind ( def_id) {
119
+ DefKind :: Struct => ( Some ( target_idx) , None ) ,
120
+ DefKind :: Enum => (
121
+ self . map . apply ( target_idx, TrackElem :: Variant ( variant_index) ) ,
122
+ Some ( variant_index) ,
123
+ ) ,
124
+ _ => return ,
155
125
}
156
126
}
157
- if let Some ( variant_index) = variant_index
158
- && let Some ( discr_idx) = self . map ( ) . apply ( target_idx, TrackElem :: Discriminant )
159
- {
160
- // We are assigning the discriminant as part of an aggregate.
161
- // This discriminant can only alias a variant field's value if the operand
162
- // had an invalid value for that type.
163
- // Using invalid values is UB, so we are allowed to perform the assignment
164
- // without extra flooding.
165
- let enum_ty = target. ty ( self . local_decls , self . tcx ) . ty ;
166
- if let Some ( discr_val) = self . eval_discriminant ( enum_ty, variant_index) {
167
- state. insert_value_idx ( discr_idx, FlatSet :: Elem ( discr_val) , & self . map ) ;
127
+ _ => return ,
128
+ } ;
129
+ if let Some ( variant_target_idx) = variant_target {
130
+ for ( field_index, operand) in operands. iter ( ) . enumerate ( ) {
131
+ if let Some ( field) = self . map ( ) . apply (
132
+ variant_target_idx,
133
+ TrackElem :: Field ( FieldIdx :: from_usize ( field_index) ) ,
134
+ ) {
135
+ let result = self . handle_operand ( operand, state) ;
136
+ state. insert_idx ( field, result, self . map ( ) ) ;
168
137
}
169
138
}
170
139
}
140
+ if let Some ( variant_index) = variant_index
141
+ && let Some ( discr_idx) = self . map ( ) . apply ( target_idx, TrackElem :: Discriminant )
142
+ {
143
+ // We are assigning the discriminant as part of an aggregate.
144
+ // This discriminant can only alias a variant field's value if the operand
145
+ // had an invalid value for that type.
146
+ // Using invalid values is UB, so we are allowed to perform the assignment
147
+ // without extra flooding.
148
+ let enum_ty = target. ty ( self . local_decls , self . tcx ) . ty ;
149
+ if let Some ( discr_val) = self . eval_discriminant ( enum_ty, variant_index) {
150
+ state. insert_value_idx ( discr_idx, FlatSet :: Elem ( discr_val) , & self . map ) ;
151
+ }
152
+ }
171
153
}
172
154
Rvalue :: CheckedBinaryOp ( op, box ( left, right) ) => {
173
155
// Flood everything now, so we can use `insert_value_idx` directly later.
174
156
state. flood ( target. as_ref ( ) , self . map ( ) ) ;
175
157
176
- let target = self . map ( ) . find ( target. as_ref ( ) ) ;
158
+ let Some ( target) = self . map ( ) . find ( target. as_ref ( ) ) else { return } ;
177
159
178
- let value_target = target
179
- . and_then ( |target| self . map ( ) . apply ( target, TrackElem :: Field ( 0_u32 . into ( ) ) ) ) ;
180
- let overflow_target = target
181
- . and_then ( |target| self . map ( ) . apply ( target, TrackElem :: Field ( 1_u32 . into ( ) ) ) ) ;
160
+ let value_target = self . map ( ) . apply ( target, TrackElem :: Field ( 0_u32 . into ( ) ) ) ;
161
+ let overflow_target = self . map ( ) . apply ( target, TrackElem :: Field ( 1_u32 . into ( ) ) ) ;
182
162
183
163
if value_target. is_some ( ) || overflow_target. is_some ( ) {
184
164
let ( val, overflow) = self . binary_op ( state, * op, left, right) ;
@@ -377,6 +357,20 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
377
357
}
378
358
}
379
359
360
+ fn eval_discriminant (
361
+ & self ,
362
+ enum_ty : Ty < ' tcx > ,
363
+ variant_index : VariantIdx ,
364
+ ) -> Option < ScalarTy < ' tcx > > {
365
+ if !enum_ty. is_enum ( ) {
366
+ return None ;
367
+ }
368
+ let discr = enum_ty. discriminant_for_variant ( self . tcx , variant_index) ?;
369
+ let discr_layout = self . tcx . layout_of ( self . param_env . and ( discr. ty ) ) . ok ( ) ?;
370
+ let discr_value = Scalar :: try_from_uint ( discr. val , discr_layout. size ) ?;
371
+ Some ( ScalarTy ( discr_value, discr. ty ) )
372
+ }
373
+
380
374
fn wrap_scalar ( & self , scalar : Scalar , ty : Ty < ' tcx > ) -> FlatSet < ScalarTy < ' tcx > > {
381
375
FlatSet :: Elem ( ScalarTy ( scalar, ty) )
382
376
}
@@ -520,21 +514,6 @@ impl<'tcx, 'map, 'a> Visitor<'tcx> for OperandCollector<'tcx, 'map, 'a> {
520
514
_ => ( ) ,
521
515
}
522
516
}
523
-
524
- fn visit_rvalue ( & mut self , rvalue : & Rvalue < ' tcx > , location : Location ) {
525
- match rvalue {
526
- Rvalue :: Discriminant ( place) => {
527
- match self . state . get_discr ( place. as_ref ( ) , self . visitor . map ) {
528
- FlatSet :: Top => ( ) ,
529
- FlatSet :: Elem ( value) => {
530
- self . visitor . before_effect . insert ( ( location, * place) , value) ;
531
- }
532
- FlatSet :: Bottom => ( ) ,
533
- }
534
- }
535
- _ => self . super_rvalue ( rvalue, location) ,
536
- }
537
- }
538
517
}
539
518
540
519
struct DummyMachine ;
0 commit comments