@@ -193,47 +193,64 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
193
193
rvalue : & Rvalue < ' tcx > ,
194
194
state : & mut State < Self :: Value > ,
195
195
) -> ValueOrPlace < Self :: Value > {
196
- match rvalue {
197
- Rvalue :: Cast (
198
- kind @ ( CastKind :: IntToInt
199
- | CastKind :: FloatToInt
200
- | CastKind :: FloatToFloat
201
- | CastKind :: IntToFloat ) ,
202
- operand,
203
- ty,
204
- ) => match self . eval_operand ( operand, state) {
205
- FlatSet :: Elem ( op) => match kind {
206
- CastKind :: IntToInt | CastKind :: IntToFloat => {
207
- self . ecx . int_to_int_or_float ( & op, * ty)
208
- }
209
- CastKind :: FloatToInt | CastKind :: FloatToFloat => {
210
- self . ecx . float_to_float_or_int ( & op, * ty)
211
- }
212
- _ => unreachable ! ( ) ,
196
+ let val = match rvalue {
197
+ Rvalue :: Cast ( CastKind :: IntToInt | CastKind :: IntToFloat , operand, ty) => {
198
+ match self . eval_operand ( operand, state) {
199
+ FlatSet :: Elem ( op) => self
200
+ . ecx
201
+ . int_to_int_or_float ( & op, * ty)
202
+ . map_or ( FlatSet :: Top , |result| self . wrap_immediate ( result, * ty) ) ,
203
+ FlatSet :: Bottom => FlatSet :: Bottom ,
204
+ FlatSet :: Top => FlatSet :: Top ,
213
205
}
214
- . map ( |result| ValueOrPlace :: Value ( self . wrap_immediate ( result, * ty) ) )
215
- . unwrap_or ( ValueOrPlace :: TOP ) ,
216
- _ => ValueOrPlace :: TOP ,
217
- } ,
206
+ }
207
+ Rvalue :: Cast ( CastKind :: FloatToInt | CastKind :: FloatToFloat , operand, ty) => {
208
+ match self . eval_operand ( operand, state) {
209
+ FlatSet :: Elem ( op) => self
210
+ . ecx
211
+ . float_to_float_or_int ( & op, * ty)
212
+ . map_or ( FlatSet :: Top , |result| self . wrap_immediate ( result, * ty) ) ,
213
+ FlatSet :: Bottom => FlatSet :: Bottom ,
214
+ FlatSet :: Top => FlatSet :: Top ,
215
+ }
216
+ }
217
+ Rvalue :: Cast ( CastKind :: Transmute , operand, ty) => {
218
+ match self . eval_operand ( operand, state) {
219
+ FlatSet :: Elem ( op) => self . wrap_immediate ( * op, * ty) ,
220
+ FlatSet :: Bottom => FlatSet :: Bottom ,
221
+ FlatSet :: Top => FlatSet :: Top ,
222
+ }
223
+ }
218
224
Rvalue :: BinaryOp ( op, box ( left, right) ) => {
219
225
// Overflows must be ignored here.
220
226
let ( val, _overflow) = self . binary_op ( state, * op, left, right) ;
221
- ValueOrPlace :: Value ( val)
227
+ val
222
228
}
223
229
Rvalue :: UnaryOp ( op, operand) => match self . eval_operand ( operand, state) {
224
- FlatSet :: Elem ( value) => self
225
- . ecx
226
- . unary_op ( * op, & value)
227
- . map ( |val| ValueOrPlace :: Value ( self . wrap_immty ( val) ) )
228
- . unwrap_or ( ValueOrPlace :: Value ( FlatSet :: Top ) ) ,
229
- FlatSet :: Bottom => ValueOrPlace :: Value ( FlatSet :: Bottom ) ,
230
- FlatSet :: Top => ValueOrPlace :: Value ( FlatSet :: Top ) ,
230
+ FlatSet :: Elem ( value) => {
231
+ self . ecx . unary_op ( * op, & value) . map_or ( FlatSet :: Top , |val| self . wrap_immty ( val) )
232
+ }
233
+ FlatSet :: Bottom => FlatSet :: Bottom ,
234
+ FlatSet :: Top => FlatSet :: Top ,
231
235
} ,
232
- Rvalue :: Discriminant ( place) => {
233
- ValueOrPlace :: Value ( state. get_discr ( place. as_ref ( ) , self . map ( ) ) )
236
+ Rvalue :: NullaryOp ( null_op, ty) => {
237
+ let Ok ( layout) = self . tcx . layout_of ( self . param_env . and ( * ty) ) else {
238
+ return ValueOrPlace :: Value ( FlatSet :: Top ) ;
239
+ } ;
240
+ let val = match null_op {
241
+ NullOp :: SizeOf if layout. is_sized ( ) => layout. size . bytes ( ) ,
242
+ NullOp :: AlignOf if layout. is_sized ( ) => layout. align . abi . bytes ( ) ,
243
+ NullOp :: OffsetOf ( fields) => layout
244
+ . offset_of_subfield ( & self . ecx , fields. iter ( ) . map ( |f| f. index ( ) ) )
245
+ . bytes ( ) ,
246
+ _ => return ValueOrPlace :: Value ( FlatSet :: Top ) ,
247
+ } ;
248
+ self . wrap_scalar ( Scalar :: from_target_usize ( val, & self . tcx ) , self . tcx . types . usize )
234
249
}
235
- _ => self . super_rvalue ( rvalue, state) ,
236
- }
250
+ Rvalue :: Discriminant ( place) => state. get_discr ( place. as_ref ( ) , self . map ( ) ) ,
251
+ _ => return self . super_rvalue ( rvalue, state) ,
252
+ } ;
253
+ ValueOrPlace :: Value ( val)
237
254
}
238
255
239
256
fn handle_constant (
0 commit comments