@@ -285,9 +285,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
285285 let ( val, overflowed) = {
286286 let a_offset = ImmTy :: from_uint ( a_offset, usize_layout) ;
287287 let b_offset = ImmTy :: from_uint ( b_offset, usize_layout) ;
288- self . overflowing_binary_op ( BinOp :: Sub , & a_offset, & b_offset) ?
288+ self . binary_op ( BinOp :: SubWithOverflow , & a_offset, & b_offset) ?
289+ . to_scalar_pair ( )
289290 } ;
290- if overflowed {
291+ if overflowed. to_bool ( ) ? {
291292 // a < b
292293 if intrinsic_name == sym:: ptr_offset_from_unsigned {
293294 throw_ub_custom ! (
@@ -299,7 +300,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
299300 // The signed form of the intrinsic allows this. If we interpret the
300301 // difference as isize, we'll get the proper signed difference. If that
301302 // seems *positive*, they were more than isize::MAX apart.
302- let dist = val. to_scalar ( ) . to_target_isize ( self ) ?;
303+ let dist = val. to_target_isize ( self ) ?;
303304 if dist >= 0 {
304305 throw_ub_custom ! (
305306 fluent:: const_eval_offset_from_underflow,
@@ -309,7 +310,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
309310 dist
310311 } else {
311312 // b >= a
312- let dist = val. to_scalar ( ) . to_target_isize ( self ) ?;
313+ let dist = val. to_target_isize ( self ) ?;
313314 // If converting to isize produced a *negative* result, we had an overflow
314315 // because they were more than isize::MAX apart.
315316 if dist < 0 {
@@ -515,17 +516,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
515516 // Performs an exact division, resulting in undefined behavior where
516517 // `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`.
517518 // First, check x % y != 0 (or if that computation overflows).
518- let ( res, overflow) = self . overflowing_binary_op ( BinOp :: Rem , a, b) ?;
519- assert ! ( !overflow) ; // All overflow is UB, so this should never return on overflow.
520- if res. to_scalar ( ) . assert_bits ( a. layout . size ) != 0 {
519+ let rem = self . binary_op ( BinOp :: Rem , a, b) ?;
520+ if rem. to_scalar ( ) . assert_bits ( a. layout . size ) != 0 {
521521 throw_ub_custom ! (
522522 fluent:: const_eval_exact_div_has_remainder,
523523 a = format!( "{a}" ) ,
524524 b = format!( "{b}" )
525525 )
526526 }
527527 // `Rem` says this is all right, so we can let `Div` do its job.
528- self . binop_ignore_overflow ( BinOp :: Div , a, b, & dest. clone ( ) . into ( ) )
528+ let res = self . binary_op ( BinOp :: Div , a, b) ?;
529+ self . write_immediate ( * res, dest)
529530 }
530531
531532 pub fn saturating_arith (
@@ -538,8 +539,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
538539 assert ! ( matches!( l. layout. ty. kind( ) , ty:: Int ( ..) | ty:: Uint ( ..) ) ) ;
539540 assert ! ( matches!( mir_op, BinOp :: Add | BinOp :: Sub ) ) ;
540541
541- let ( val, overflowed) = self . overflowing_binary_op ( mir_op, l, r) ?;
542- Ok ( if overflowed {
542+ let ( val, overflowed) =
543+ self . binary_op ( mir_op. wrapping_to_overflowing ( ) . unwrap ( ) , l, r) ?. to_scalar_pair ( ) ;
544+ Ok ( if overflowed. to_bool ( ) ? {
543545 let size = l. layout . size ;
544546 let num_bits = size. bits ( ) ;
545547 if l. layout . abi . is_signed ( ) {
@@ -570,7 +572,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
570572 }
571573 }
572574 } else {
573- val. to_scalar ( )
575+ val
574576 } )
575577 }
576578
0 commit comments