File tree Expand file tree Collapse file tree 2 files changed +14
-8
lines changed
src/librustc_middle/mir/interpret Expand file tree Collapse file tree 2 files changed +14
-8
lines changed Original file line number Diff line number Diff line change @@ -598,3 +598,12 @@ pub fn truncate(value: u128, size: Size) -> u128 {
598598 // Truncate (shift left to drop out leftover values, shift right to fill with zeroes).
599599 ( value << shift) >> shift
600600}
601+
602+ /// Computes the unsigned absolute value without wrapping or panicking.
603+ #[ inline]
604+ pub fn uabs ( value : i64 ) -> u64 {
605+ // The only tricky part here is if value == i64::MIN. In that case,
606+ // wrapping_abs() returns i64::MIN == -2^63. Casting this value to a u64
607+ // gives 2^63, the correct value.
608+ value. wrapping_abs ( ) as u64
609+ }
Original file line number Diff line number Diff line change 1- use super :: { AllocId , InterpResult } ;
1+ use super :: { uabs , AllocId , InterpResult } ;
22
33use rustc_macros:: HashStable ;
44use rustc_target:: abi:: { HasDataLayout , Size } ;
@@ -48,15 +48,12 @@ pub trait PointerArithmetic: HasDataLayout {
4848
4949 #[ inline]
5050 fn overflowing_signed_offset ( & self , val : u64 , i : i64 ) -> ( u64 , bool ) {
51- if i < 0 {
52- // Trickery to ensure that `i64::MIN` works fine: compute `n = -i`.
53- // This formula only works for true negative values; it overflows for zero!
54- let n = u64 :: MAX - ( i as u64 ) + 1 ;
51+ let n = uabs ( i ) ;
52+ if i >= 0 {
53+ self . overflowing_offset ( val , n )
54+ } else {
5555 let res = val. overflowing_sub ( n) ;
5656 self . truncate_to_ptr ( res)
57- } else {
58- // `i >= 0`, so the cast is safe.
59- self . overflowing_offset ( val, i as u64 )
6057 }
6158 }
6259
You can’t perform that action at this time.
0 commit comments