@@ -410,8 +410,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
410410 ) -> InterpResult < ' tcx > {
411411 // Performs an exact division, resulting in undefined behavior where
412412 // `x % y != 0` or `y == 0` or `x == T::min_value() && y == -1`.
413- // First, check x % y != 0.
414- if self . binary_op ( BinOp :: Rem , a, b) ?. to_bits ( ) ? != 0 {
413+ // First, check x % y != 0 (or if that computation overflows).
414+ let ( res, overflow, _ty) = self . overflowing_binary_op ( BinOp :: Rem , a, b) ?;
415+ if overflow || res. to_bits ( a. layout . size ) ? != 0 {
415416 // Then, check if `b` is -1, which is the "min_value / -1" case.
416417 let minus1 = Scalar :: from_int ( -1 , dest. layout . size ) ;
417418 let b_scalar = b. to_scalar ( ) . unwrap ( ) ;
@@ -421,6 +422,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
421422 throw_ub_format ! ( "exact_div: {} cannot be divided by {} without remainder" , a, b, )
422423 }
423424 }
425+ // `Rem` says this is all right, so we can let `Div` do its job.
424426 self . binop_ignore_overflow ( BinOp :: Div , a, b, dest)
425427 }
426428}
0 commit comments