@@ -285,9 +285,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
285
285
let ( val, overflowed) = {
286
286
let a_offset = ImmTy :: from_uint ( a_offset, usize_layout) ;
287
287
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 ( )
289
290
} ;
290
- if overflowed {
291
+ if overflowed. to_bool ( ) ? {
291
292
// a < b
292
293
if intrinsic_name == sym:: ptr_offset_from_unsigned {
293
294
throw_ub_custom ! (
@@ -299,7 +300,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
299
300
// The signed form of the intrinsic allows this. If we interpret the
300
301
// difference as isize, we'll get the proper signed difference. If that
301
302
// 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 ) ?;
303
304
if dist >= 0 {
304
305
throw_ub_custom ! (
305
306
fluent:: const_eval_offset_from_underflow,
@@ -309,7 +310,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
309
310
dist
310
311
} else {
311
312
// b >= a
312
- let dist = val. to_scalar ( ) . to_target_isize ( self ) ?;
313
+ let dist = val. to_target_isize ( self ) ?;
313
314
// If converting to isize produced a *negative* result, we had an overflow
314
315
// because they were more than isize::MAX apart.
315
316
if dist < 0 {
@@ -515,17 +516,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
515
516
// Performs an exact division, resulting in undefined behavior where
516
517
// `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`.
517
518
// 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 {
521
521
throw_ub_custom ! (
522
522
fluent:: const_eval_exact_div_has_remainder,
523
523
a = format!( "{a}" ) ,
524
524
b = format!( "{b}" )
525
525
)
526
526
}
527
527
// `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)
529
530
}
530
531
531
532
pub fn saturating_arith (
@@ -538,8 +539,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
538
539
assert ! ( matches!( l. layout. ty. kind( ) , ty:: Int ( ..) | ty:: Uint ( ..) ) ) ;
539
540
assert ! ( matches!( mir_op, BinOp :: Add | BinOp :: Sub ) ) ;
540
541
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 ( ) ? {
543
545
let size = l. layout . size ;
544
546
let num_bits = size. bits ( ) ;
545
547
if l. layout . abi . is_signed ( ) {
@@ -570,7 +572,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
570
572
}
571
573
}
572
574
} else {
573
- val. to_scalar ( )
575
+ val
574
576
} )
575
577
}
576
578
0 commit comments