@@ -9,7 +9,7 @@ pub trait EvalContextExt<'tcx> {
99 ptr : Pointer < Tag >
1010 ) -> InterpResult < ' tcx > ;
1111
12- fn ptr_op (
12+ fn binary_ptr_op (
1313 & self ,
1414 bin_op : mir:: BinOp ,
1515 left : ImmTy < ' tcx , Tag > ,
@@ -46,7 +46,7 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
4646 ptr. check_in_alloc ( size, CheckInAllocMsg :: InboundsTest )
4747 }
4848
49- fn ptr_op (
49+ fn binary_ptr_op (
5050 & self ,
5151 bin_op : mir:: BinOp ,
5252 left : ImmTy < ' tcx , Tag > ,
@@ -56,21 +56,6 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
5656
5757 trace ! ( "ptr_op: {:?} {:?} {:?}" , * left, bin_op, * right) ;
5858
59- // Treat everything of integer *type* at integer *value*.
60- if left. layout . ty . is_integral ( ) {
61- // This is actually an integer operation, so dispatch back to the core engine.
62- // TODO: Once intptrcast is the default, librustc_mir should never even call us
63- // for integer types.
64- assert ! ( right. layout. ty. is_integral( ) ) ;
65- let l_bits = self . force_bits ( left. imm . to_scalar ( ) ?, left. layout . size ) ?;
66- let r_bits = self . force_bits ( right. imm . to_scalar ( ) ?, right. layout . size ) ?;
67-
68- let left = ImmTy :: from_scalar ( Scalar :: from_uint ( l_bits, left. layout . size ) , left. layout ) ;
69- let right = ImmTy :: from_scalar ( Scalar :: from_uint ( r_bits, left. layout . size ) , right. layout ) ;
70-
71- return self . binary_op ( bin_op, left, right) ;
72- }
73-
7459 // Operations that support fat pointers
7560 match bin_op {
7661 Eq | Ne => {
@@ -92,7 +77,6 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
9277 let left = left. to_scalar ( ) ?;
9378 let right_layout = right. layout ;
9479 let right = right. to_scalar ( ) ?;
95- debug_assert ! ( left. is_ptr( ) || right. is_ptr( ) || bin_op == Offset ) ;
9680
9781 Ok ( match bin_op {
9882 Offset => {
@@ -109,8 +93,8 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
10993 }
11094 // These need both to be pointer, and fail if they are not in the same location
11195 Lt | Le | Gt | Ge | Sub if left. is_ptr ( ) && right. is_ptr ( ) => {
112- let left = left. to_ptr ( ) . expect ( "we checked is_ptr" ) ;
113- let right = right. to_ptr ( ) . expect ( "we checked is_ptr" ) ;
96+ let left = left. assert_ptr ( ) ;
97+ let right = right. assert_ptr ( ) ;
11498 if left. alloc_id == right. alloc_id {
11599 let res = match bin_op {
116100 Lt => left. offset < right. offset ,
@@ -136,10 +120,22 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
136120 throw_unsup ! ( InvalidPointerMath )
137121 }
138122 }
123+ Lt | Le | Gt | Ge if left. is_bits ( ) && right. is_bits ( ) => {
124+ let left = left. assert_bits ( self . memory ( ) . pointer_size ( ) ) ;
125+ let right = right. assert_bits ( self . memory ( ) . pointer_size ( ) ) ;
126+ let res = match bin_op {
127+ Lt => left < right,
128+ Le => left <= right,
129+ Gt => left > right,
130+ Ge => left >= right,
131+ _ => bug ! ( "We already established it has to be one of these operators." ) ,
132+ } ;
133+ Ok ( ( Scalar :: from_bool ( res) , false ) )
134+ }
139135 Gt | Ge if left. is_ptr ( ) && right. is_bits ( ) => {
140136 // "ptr >[=] integer" can be tested if the integer is small enough.
141- let left = left. to_ptr ( ) . expect ( "we checked is_ptr" ) ;
142- let right = right. to_bits ( self . memory ( ) . pointer_size ( ) ) . expect ( "we checked is_bits" ) ;
137+ let left = left. assert_ptr ( ) ;
138+ let right = right. assert_bits ( self . memory ( ) . pointer_size ( ) ) ;
143139 let ( _alloc_size, alloc_align) = self . memory ( )
144140 . get_size_and_align ( left. alloc_id , AllocCheck :: MaybeDead )
145141 . expect ( "alloc info with MaybeDead cannot fail" ) ;
@@ -162,8 +158,8 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
162158 // Cast to i128 is fine as we checked the kind to be ptr-sized
163159 self . ptr_int_arithmetic (
164160 bin_op,
165- left. to_ptr ( ) . expect ( "we checked is_ptr" ) ,
166- right. to_bits ( self . memory ( ) . pointer_size ( ) ) . expect ( "we checked is_bits" ) ,
161+ left. assert_ptr ( ) ,
162+ right. assert_bits ( self . memory ( ) . pointer_size ( ) ) ,
167163 right_layout. abi . is_signed ( ) ,
168164 ) ?
169165 }
@@ -172,8 +168,8 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
172168 // This is a commutative operation, just swap the operands
173169 self . ptr_int_arithmetic (
174170 bin_op,
175- right. to_ptr ( ) . expect ( "we checked is_ptr" ) ,
176- left. to_bits ( self . memory ( ) . pointer_size ( ) ) . expect ( "we checked is_bits" ) ,
171+ right. assert_ptr ( ) ,
172+ left. assert_bits ( self . memory ( ) . pointer_size ( ) ) ,
177173 left_layout. abi . is_signed ( ) ,
178174 ) ?
179175 }
0 commit comments