@@ -193,47 +193,64 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
193193 rvalue : & Rvalue < ' tcx > ,
194194 state : & mut State < Self :: Value > ,
195195 ) -> 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) ) ,
203+ FlatSet :: Bottom => FlatSet :: Bottom ,
204+ FlatSet :: Top => FlatSet :: Top ,
213205 }
214- . map ( |result| ValueOrPlace :: Value ( self . wrap_immediate ( result) ) )
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) ) ,
213+ FlatSet :: Bottom => FlatSet :: Bottom ,
214+ FlatSet :: Top => FlatSet :: Top ,
215+ }
216+ }
217+ Rvalue :: Cast ( CastKind :: Transmute , operand, _) => {
218+ match self . eval_operand ( operand, state) {
219+ FlatSet :: Elem ( op) => self . wrap_immediate ( * op) ,
220+ FlatSet :: Bottom => FlatSet :: Bottom ,
221+ FlatSet :: Top => FlatSet :: Top ,
222+ }
223+ }
218224 Rvalue :: BinaryOp ( op, box ( left, right) ) => {
219225 // Overflows must be ignored here.
220226 let ( val, _overflow) = self . binary_op ( state, * op, left, right) ;
221- ValueOrPlace :: Value ( val)
227+ val
222228 }
223229 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 ,
231235 } ,
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+ ScalarInt :: try_from_target_usize ( val, self . tcx ) . map_or ( FlatSet :: Top , FlatSet :: Elem )
234249 }
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)
237254 }
238255
239256 fn handle_constant (
0 commit comments