about summary refs log tree commit diff
diff options
context:
space:
mode:
authorkennytm <kennytm@gmail.com>2018-09-07 13:47:24 +0800
committerkennytm <kennytm@gmail.com>2018-09-07 18:13:59 +0800
commitdcca8e86b1db4ef4fe4e6ec764b02f041e6dc159 (patch)
tree2e25f39f9ccafe5b77cd4f5f6ef5e0351de98b90
parent9b70ef7780ee3afdf68700b64327353babae9310 (diff)
parent43eb9259ec92561033969118d1cc071a91f86084 (diff)
downloadrust-dcca8e86b1db4ef4fe4e6ec764b02f041e6dc159.tar.gz
rust-dcca8e86b1db4ef4fe4e6ec764b02f041e6dc159.zip
Rollup merge of #53991 - TimDiekmann:fix-unchecked-intrinsics, r=oli-obk
Add unchecked_shl/shr check for intrinsics to fix miri's test suit

r? @RalfJung

cc @oli-obk

#53697 broke miri's test suite as described in [this comment](https://github.com/rust-lang/rust/pull/53697#issuecomment-419034668). This PR adds test for the `unchecked_shr/shl` for the intrinsics.
-rw-r--r--src/librustc_mir/interpret/intrinsics.rs22
-rw-r--r--src/test/ui/consts/const-int-unchecked.rs21
-rw-r--r--src/test/ui/consts/const-int-unchecked.stderr20
3 files changed, 59 insertions, 4 deletions
diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs
index 8cdb0e37f55..48085c21454 100644
--- a/src/librustc_mir/interpret/intrinsics.rs
+++ b/src/librustc_mir/interpret/intrinsics.rs
@@ -105,8 +105,6 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
             | "overflowing_add"
             | "overflowing_sub"
             | "overflowing_mul"
-            | "unchecked_shl"
-            | "unchecked_shr"
             | "add_with_overflow"
             | "sub_with_overflow"
             | "mul_with_overflow" => {
@@ -116,8 +114,6 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
                     "overflowing_add" => (BinOp::Add, true),
                     "overflowing_sub" => (BinOp::Sub, true),
                     "overflowing_mul" => (BinOp::Mul, true),
-                    "unchecked_shl" => (BinOp::Shl, true),
-                    "unchecked_shr" => (BinOp::Shr, true),
                     "add_with_overflow" => (BinOp::Add, false),
                     "sub_with_overflow" => (BinOp::Sub, false),
                     "mul_with_overflow" => (BinOp::Mul, false),
@@ -129,6 +125,24 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
                     self.binop_with_overflow(bin_op, lhs, rhs, dest)?;
                 }
             }
+            "unchecked_shl" | "unchecked_shr" => {
+                let l = self.read_value(args[0])?;
+                let r = self.read_value(args[1])?;
+                let bin_op = match intrinsic_name {
+                    "unchecked_shl" => BinOp::Shl,
+                    "unchecked_shr" => BinOp::Shr,
+                    _ => bug!("Already checked for int ops")
+                };
+                let (val, overflowed) = self.binary_op_val(bin_op, l, r)?;
+                if overflowed {
+                    let layout = self.layout_of(substs.type_at(0))?;
+                    let r_val =  r.to_scalar()?.to_bits(layout.size)?;
+                    return err!(Intrinsic(
+                        format!("Overflowing shift by {} in {}", r_val, intrinsic_name),
+                    ));
+                }
+                self.write_scalar(val, dest)?;
+            }
             "transmute" => {
                 // Go through an allocation, to make sure the completely different layouts
                 // do not pose a problem.  (When the user transmutes through a union,
diff --git a/src/test/ui/consts/const-int-unchecked.rs b/src/test/ui/consts/const-int-unchecked.rs
new file mode 100644
index 00000000000..cbf855633fd
--- /dev/null
+++ b/src/test/ui/consts/const-int-unchecked.rs
@@ -0,0 +1,21 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(core_intrinsics)]
+
+use std::intrinsics;
+
+const SHR: u8 = unsafe { intrinsics::unchecked_shr(5_u8, 8) };
+//^~ ERROR: Overflowing shift by 8 in unchecked_shr
+const SHL: u8 = unsafe { intrinsics::unchecked_shl(5_u8, 8) };
+//^~ ERROR: Overflowing shift by 8 in unchecked_shl
+
+fn main() {
+}
diff --git a/src/test/ui/consts/const-int-unchecked.stderr b/src/test/ui/consts/const-int-unchecked.stderr
new file mode 100644
index 00000000000..b8fd0facbc1
--- /dev/null
+++ b/src/test/ui/consts/const-int-unchecked.stderr
@@ -0,0 +1,20 @@
+error: this constant cannot be used
+  --> $DIR/const-int-unchecked.rs:15:1
+   |
+LL | const SHR: u8 = unsafe { intrinsics::unchecked_shr(5_u8, 8) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^^^
+   |                          |
+   |                          Overflowing shift by 8 in unchecked_shr
+   |
+   = note: #[deny(const_err)] on by default
+
+error: this constant cannot be used
+  --> $DIR/const-int-unchecked.rs:17:1
+   |
+LL | const SHL: u8 = unsafe { intrinsics::unchecked_shl(5_u8, 8) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^^^
+   |                          |
+   |                          Overflowing shift by 8 in unchecked_shl
+
+error: aborting due to 2 previous errors
+