@@ -5,7 +5,7 @@ use rustc_data_structures::static_assert_size;
5
5
use rustc_macros:: { HashStable , TyDecodable , TyEncodable } ;
6
6
use rustc_target:: abi:: { HasDataLayout , Size } ;
7
7
8
- use super :: { AllocId , InterpResult } ;
8
+ use super :: AllocId ;
9
9
10
10
////////////////////////////////////////////////////////////////////////////////
11
11
// Pointer arithmetic
@@ -40,62 +40,13 @@ pub trait PointerArithmetic: HasDataLayout {
40
40
}
41
41
42
42
#[ inline]
43
- fn target_usize_to_isize ( & self , val : u64 ) -> i64 {
44
- let val = val as i64 ;
45
- // Now wrap-around into the machine_isize range.
46
- if val > self . target_isize_max ( ) {
47
- // This can only happen if the ptr size is < 64, so we know max_usize_plus_1 fits into
48
- // i64.
49
- debug_assert ! ( self . pointer_size( ) . bits( ) < 64 ) ;
50
- let max_usize_plus_1 = 1u128 << self . pointer_size ( ) . bits ( ) ;
51
- val - i64:: try_from ( max_usize_plus_1) . unwrap ( )
52
- } else {
53
- val
54
- }
55
- }
56
-
57
- /// Helper function: truncate given value-"overflowed flag" pair to pointer size and
58
- /// update "overflowed flag" if there was an overflow.
59
- /// This should be called by all the other methods before returning!
60
- #[ inline]
61
- fn truncate_to_ptr ( & self , ( val, over) : ( u64 , bool ) ) -> ( u64 , bool ) {
62
- let val = u128:: from ( val) ;
63
- let max_ptr_plus_1 = 1u128 << self . pointer_size ( ) . bits ( ) ;
64
- ( u64:: try_from ( val % max_ptr_plus_1) . unwrap ( ) , over || val >= max_ptr_plus_1)
65
- }
66
-
67
- #[ inline]
68
- fn overflowing_offset ( & self , val : u64 , i : u64 ) -> ( u64 , bool ) {
69
- // We do not need to check if i fits in a machine usize. If it doesn't,
70
- // either the wrapping_add will wrap or res will not fit in a pointer.
71
- let res = val. overflowing_add ( i) ;
72
- self . truncate_to_ptr ( res)
73
- }
74
-
75
- #[ inline]
76
- fn overflowing_signed_offset ( & self , val : u64 , i : i64 ) -> ( u64 , bool ) {
77
- // We need to make sure that i fits in a machine isize.
78
- let n = i. unsigned_abs ( ) ;
79
- if i >= 0 {
80
- let ( val, over) = self . overflowing_offset ( val, n) ;
81
- ( val, over || i > self . target_isize_max ( ) )
82
- } else {
83
- let res = val. overflowing_sub ( n) ;
84
- let ( val, over) = self . truncate_to_ptr ( res) ;
85
- ( val, over || i < self . target_isize_min ( ) )
86
- }
87
- }
88
-
89
- #[ inline]
90
- fn offset < ' tcx > ( & self , val : u64 , i : u64 ) -> InterpResult < ' tcx , u64 > {
91
- let ( res, over) = self . overflowing_offset ( val, i) ;
92
- if over { throw_ub ! ( PointerArithOverflow ) } else { Ok ( res) }
43
+ fn truncate_to_target_usize ( & self , val : u64 ) -> u64 {
44
+ self . pointer_size ( ) . truncate ( val. into ( ) ) . try_into ( ) . unwrap ( )
93
45
}
94
46
95
47
#[ inline]
96
- fn signed_offset < ' tcx > ( & self , val : u64 , i : i64 ) -> InterpResult < ' tcx , u64 > {
97
- let ( res, over) = self . overflowing_signed_offset ( val, i) ;
98
- if over { throw_ub ! ( PointerArithOverflow ) } else { Ok ( res) }
48
+ fn sign_extend_to_target_isize ( & self , val : u64 ) -> i64 {
49
+ self . pointer_size ( ) . sign_extend ( val. into ( ) ) . try_into ( ) . unwrap ( )
99
50
}
100
51
}
101
52
@@ -331,7 +282,7 @@ impl<Prov> Pointer<Option<Prov>> {
331
282
}
332
283
}
333
284
334
- impl < ' tcx , Prov > Pointer < Prov > {
285
+ impl < Prov > Pointer < Prov > {
335
286
#[ inline( always) ]
336
287
pub fn new ( provenance : Prov , offset : Size ) -> Self {
337
288
Pointer { provenance, offset }
@@ -349,43 +300,16 @@ impl<'tcx, Prov> Pointer<Prov> {
349
300
Pointer { provenance : f ( self . provenance ) , ..self }
350
301
}
351
302
352
- #[ inline]
353
- pub fn offset ( self , i : Size , cx : & impl HasDataLayout ) -> InterpResult < ' tcx , Self > {
354
- Ok ( Pointer {
355
- offset : Size :: from_bytes ( cx. data_layout ( ) . offset ( self . offset . bytes ( ) , i. bytes ( ) ) ?) ,
356
- ..self
357
- } )
358
- }
359
-
360
- #[ inline]
361
- pub fn overflowing_offset ( self , i : Size , cx : & impl HasDataLayout ) -> ( Self , bool ) {
362
- let ( res, over) = cx. data_layout ( ) . overflowing_offset ( self . offset . bytes ( ) , i. bytes ( ) ) ;
363
- let ptr = Pointer { offset : Size :: from_bytes ( res) , ..self } ;
364
- ( ptr, over)
365
- }
366
-
367
303
#[ inline( always) ]
368
304
pub fn wrapping_offset ( self , i : Size , cx : & impl HasDataLayout ) -> Self {
369
- self . overflowing_offset ( i, cx) . 0
370
- }
371
-
372
- #[ inline]
373
- pub fn signed_offset ( self , i : i64 , cx : & impl HasDataLayout ) -> InterpResult < ' tcx , Self > {
374
- Ok ( Pointer {
375
- offset : Size :: from_bytes ( cx. data_layout ( ) . signed_offset ( self . offset . bytes ( ) , i) ?) ,
376
- ..self
377
- } )
378
- }
379
-
380
- #[ inline]
381
- pub fn overflowing_signed_offset ( self , i : i64 , cx : & impl HasDataLayout ) -> ( Self , bool ) {
382
- let ( res, over) = cx. data_layout ( ) . overflowing_signed_offset ( self . offset . bytes ( ) , i) ;
383
- let ptr = Pointer { offset : Size :: from_bytes ( res) , ..self } ;
384
- ( ptr, over)
305
+ let res =
306
+ cx. data_layout ( ) . truncate_to_target_usize ( self . offset . bytes ( ) . wrapping_add ( i. bytes ( ) ) ) ;
307
+ Pointer { offset : Size :: from_bytes ( res) , ..self }
385
308
}
386
309
387
310
#[ inline( always) ]
388
311
pub fn wrapping_signed_offset ( self , i : i64 , cx : & impl HasDataLayout ) -> Self {
389
- self . overflowing_signed_offset ( i, cx) . 0
312
+ // It's wrapping anyway, so we can just cast to `u64`.
313
+ self . wrapping_offset ( Size :: from_bytes ( i as u64 ) , cx)
390
314
}
391
315
}
0 commit comments