@@ -286,9 +286,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
286286 let ( val, overflowed) = {
287287 let a_offset = ImmTy :: from_uint ( a_offset, usize_layout) ;
288288 let b_offset = ImmTy :: from_uint ( b_offset, usize_layout) ;
289- self . overflowing_binary_op ( BinOp :: Sub , & a_offset, & b_offset) ?
289+ self . binary_op ( BinOp :: SubWithOverflow , & a_offset, & b_offset) ?
290+ . to_scalar_pair ( )
290291 } ;
291- if overflowed {
292+ if overflowed. to_bool ( ) ? {
292293 // a < b
293294 if intrinsic_name == sym:: ptr_offset_from_unsigned {
294295 throw_ub_custom ! (
@@ -300,7 +301,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
300301 // The signed form of the intrinsic allows this. If we interpret the
301302 // difference as isize, we'll get the proper signed difference. If that
302303 // seems *positive*, they were more than isize::MAX apart.
303- let dist = val. to_scalar ( ) . to_target_isize ( self ) ?;
304+ let dist = val. to_target_isize ( self ) ?;
304305 if dist >= 0 {
305306 throw_ub_custom ! (
306307 fluent:: const_eval_offset_from_underflow,
@@ -310,7 +311,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
310311 dist
311312 } else {
312313 // b >= a
313- let dist = val. to_scalar ( ) . to_target_isize ( self ) ?;
314+ let dist = val. to_target_isize ( self ) ?;
314315 // If converting to isize produced a *negative* result, we had an overflow
315316 // because they were more than isize::MAX apart.
316317 if dist < 0 {
@@ -516,17 +517,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
516517 // Performs an exact division, resulting in undefined behavior where
517518 // `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`.
518519 // First, check x % y != 0 (or if that computation overflows).
519- let ( res, overflow) = self . overflowing_binary_op ( BinOp :: Rem , a, b) ?;
520- assert ! ( !overflow) ; // All overflow is UB, so this should never return on overflow.
521- if res. to_scalar ( ) . assert_bits ( a. layout . size ) != 0 {
520+ let rem = self . binary_op ( BinOp :: Rem , a, b) ?;
521+ if rem. to_scalar ( ) . assert_bits ( a. layout . size ) != 0 {
522522 throw_ub_custom ! (
523523 fluent:: const_eval_exact_div_has_remainder,
524524 a = format!( "{a}" ) ,
525525 b = format!( "{b}" )
526526 )
527527 }
528528 // `Rem` says this is all right, so we can let `Div` do its job.
529- self . binop_ignore_overflow ( BinOp :: Div , a, b, & dest. clone ( ) . into ( ) )
529+ let res = self . binary_op ( BinOp :: Div , a, b) ?;
530+ self . write_immediate ( * res, dest)
530531 }
531532
532533 pub fn saturating_arith (
@@ -539,8 +540,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
539540 assert ! ( matches!( l. layout. ty. kind( ) , ty:: Int ( ..) | ty:: Uint ( ..) ) ) ;
540541 assert ! ( matches!( mir_op, BinOp :: Add | BinOp :: Sub ) ) ;
541542
542- let ( val, overflowed) = self . overflowing_binary_op ( mir_op, l, r) ?;
543- Ok ( if overflowed {
543+ let ( val, overflowed) =
544+ self . binary_op ( mir_op. wrapping_to_overflowing ( ) . unwrap ( ) , l, r) ?. to_scalar_pair ( ) ;
545+ Ok ( if overflowed. to_bool ( ) ? {
544546 let size = l. layout . size ;
545547 let num_bits = size. bits ( ) ;
546548 if l. layout . abi . is_signed ( ) {
@@ -571,7 +573,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
571573 }
572574 }
573575 } else {
574- val. to_scalar ( )
576+ val
575577 } )
576578 }
577579
0 commit comments