From 28f85c6ffad77554150e7cab4ccac38b26621bdb Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 9 Feb 2020 15:41:40 +0100 Subject: [PATCH] bring back extra check for int_min%-1 --- src/librustc_mir/interpret/operator.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs index b4f6b5f89996..abe437bd8d7c 100644 --- a/src/librustc_mir/interpret/operator.rs +++ b/src/librustc_mir/interpret/operator.rs @@ -195,6 +195,17 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { if let Some(op) = op { let l128 = self.sign_extend(l, left_layout) as i128; let r = self.sign_extend(r, right_layout) as i128; + // We need a special check for overflowing remainder: + // "int_min % -1" overflows and returns 0, but after casting things to a larger int + // type it does *not* overflow nor give an unrepresentable result! + match bin_op { + Rem => { + if r == -1 && l == (1 << (size.bits() - 1)) { + return Ok((Scalar::from_int(0, size), true, left_layout.ty)); + } + } + _ => {} + } let (result, oflo) = op(l128, r); // This may be out-of-bounds for the result type, so we have to truncate ourselves.