@@ -5,7 +5,7 @@ use rustc_data_structures::static_assert_size;
55use rustc_macros:: { HashStable , TyDecodable , TyEncodable } ;
66use rustc_target:: abi:: { HasDataLayout , Size } ;
77
8- use super :: { AllocId , InterpResult } ;
8+ use super :: AllocId ;
99
1010////////////////////////////////////////////////////////////////////////////////
1111// Pointer arithmetic
@@ -40,62 +40,13 @@ pub trait PointerArithmetic: HasDataLayout {
4040 }
4141
4242 #[ 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 ( )
9345 }
9446
9547 #[ 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 ( )
9950 }
10051}
10152
@@ -331,7 +282,7 @@ impl<Prov> Pointer<Option<Prov>> {
331282 }
332283}
333284
334- impl < ' tcx , Prov > Pointer < Prov > {
285+ impl < Prov > Pointer < Prov > {
335286 #[ inline( always) ]
336287 pub fn new ( provenance : Prov , offset : Size ) -> Self {
337288 Pointer { provenance, offset }
@@ -349,43 +300,16 @@ impl<'tcx, Prov> Pointer<Prov> {
349300 Pointer { provenance : f ( self . provenance ) , ..self }
350301 }
351302
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-
367303 #[ inline( always) ]
368304 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 }
385308 }
386309
387310 #[ inline( always) ]
388311 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)
390314 }
391315}
0 commit comments