diff options
| author | Ralf Jung <post@ralfj.de> | 2020-02-09 15:41:40 +0100 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2020-02-09 15:41:54 +0100 |
| commit | 28f85c6ffad77554150e7cab4ccac38b26621bdb (patch) | |
| tree | 832043532309caf3ae721c2b6cd129de8378281a | |
| parent | 202d401c2504f17133c50505b82fe4278ab2c842 (diff) | |
| download | rust-28f85c6ffad77554150e7cab4ccac38b26621bdb.tar.gz rust-28f85c6ffad77554150e7cab4ccac38b26621bdb.zip | |
bring back extra check for int_min%-1
| -rw-r--r-- | src/librustc_mir/interpret/operator.rs | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs index b4f6b5f8999..abe437bd8d7 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. |
