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