@@ -9,7 +9,7 @@ pub trait EvalContextExt<'tcx> {
9
9
ptr : Pointer < Tag >
10
10
) -> InterpResult < ' tcx > ;
11
11
12
- fn ptr_op (
12
+ fn binary_ptr_op (
13
13
& self ,
14
14
bin_op : mir:: BinOp ,
15
15
left : ImmTy < ' tcx , Tag > ,
@@ -46,7 +46,7 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
46
46
ptr. check_in_alloc ( size, CheckInAllocMsg :: InboundsTest )
47
47
}
48
48
49
- fn ptr_op (
49
+ fn binary_ptr_op (
50
50
& self ,
51
51
bin_op : mir:: BinOp ,
52
52
left : ImmTy < ' tcx , Tag > ,
@@ -56,21 +56,6 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
56
56
57
57
trace ! ( "ptr_op: {:?} {:?} {:?}" , * left, bin_op, * right) ;
58
58
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
-
74
59
// Operations that support fat pointers
75
60
match bin_op {
76
61
Eq | Ne => {
@@ -92,7 +77,6 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
92
77
let left = left. to_scalar ( ) ?;
93
78
let right_layout = right. layout ;
94
79
let right = right. to_scalar ( ) ?;
95
- debug_assert ! ( left. is_ptr( ) || right. is_ptr( ) || bin_op == Offset ) ;
96
80
97
81
Ok ( match bin_op {
98
82
Offset => {
@@ -109,8 +93,8 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
109
93
}
110
94
// These need both to be pointer, and fail if they are not in the same location
111
95
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 ( ) ;
114
98
if left. alloc_id == right. alloc_id {
115
99
let res = match bin_op {
116
100
Lt => left. offset < right. offset ,
@@ -136,10 +120,22 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
136
120
throw_unsup ! ( InvalidPointerMath )
137
121
}
138
122
}
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
+ }
139
135
Gt | Ge if left. is_ptr ( ) && right. is_bits ( ) => {
140
136
// "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 ( ) ) ;
143
139
let ( _alloc_size, alloc_align) = self . memory ( )
144
140
. get_size_and_align ( left. alloc_id , AllocCheck :: MaybeDead )
145
141
. expect ( "alloc info with MaybeDead cannot fail" ) ;
@@ -162,8 +158,8 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
162
158
// Cast to i128 is fine as we checked the kind to be ptr-sized
163
159
self . ptr_int_arithmetic (
164
160
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 ( ) ) ,
167
163
right_layout. abi . is_signed ( ) ,
168
164
) ?
169
165
}
@@ -172,8 +168,8 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
172
168
// This is a commutative operation, just swap the operands
173
169
self . ptr_int_arithmetic (
174
170
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 ( ) ) ,
177
173
left_layout. abi . is_signed ( ) ,
178
174
) ?
179
175
}
0 commit comments