about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorDylan MacKenzie <ecstaticmorse@gmail.com>2020-02-04 17:09:22 -0800
committerDylan MacKenzie <ecstaticmorse@gmail.com>2020-02-04 20:36:18 -0800
commit78f8ad36409754319011514ca6febc8599abd429 (patch)
tree40acf981fa441776ad6080604ed96cb63234065a /src
parent040d9873aa6ca1ce458e98fec403cee8ec4f7ae8 (diff)
downloadrust-78f8ad36409754319011514ca6febc8599abd429.tar.gz
rust-78f8ad36409754319011514ca6febc8599abd429.zip
Implement remaining `unchecked` arithmetic intrinsics
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/interpret/intrinsics.rs19
-rw-r--r--src/librustc_span/symbol.rs5
2 files changed, 22 insertions, 2 deletions
diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs
index cd6d94357e4..f85da760ada 100644
--- a/src/librustc_mir/interpret/intrinsics.rs
+++ b/src/librustc_mir/interpret/intrinsics.rs
@@ -218,19 +218,34 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 };
                 self.write_scalar(val, dest)?;
             }
-            sym::unchecked_shl | sym::unchecked_shr => {
+            sym::unchecked_shl
+            | sym::unchecked_shr
+            | sym::unchecked_add
+            | sym::unchecked_sub
+            | sym::unchecked_mul
+            | sym::unchecked_div
+            | sym::unchecked_rem => {
                 let l = self.read_immediate(args[0])?;
                 let r = self.read_immediate(args[1])?;
                 let bin_op = match intrinsic_name {
                     sym::unchecked_shl => BinOp::Shl,
                     sym::unchecked_shr => BinOp::Shr,
+                    sym::unchecked_add => BinOp::Add,
+                    sym::unchecked_sub => BinOp::Sub,
+                    sym::unchecked_mul => BinOp::Mul,
+                    sym::unchecked_div => BinOp::Div,
+                    sym::unchecked_rem => BinOp::Rem,
                     _ => bug!("Already checked for int ops"),
                 };
                 let (val, overflowed, _ty) = self.overflowing_binary_op(bin_op, l, r)?;
                 if overflowed {
                     let layout = self.layout_of(substs.type_at(0))?;
                     let r_val = self.force_bits(r.to_scalar()?, layout.size)?;
-                    throw_ub_format!("Overflowing shift by {} in `{}`", r_val, intrinsic_name);
+                    if let sym::unchecked_shl | sym::unchecked_shr = intrinsic_name {
+                        throw_ub_format!("Overflowing shift by {} in `{}`", r_val, intrinsic_name);
+                    } else {
+                        throw_ub_format!("Overflow executing `{}`", intrinsic_name);
+                    }
                 }
                 self.write_scalar(val, dest)?;
             }
diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs
index e4f8b5a0143..c060e8948e3 100644
--- a/src/librustc_span/symbol.rs
+++ b/src/librustc_span/symbol.rs
@@ -755,8 +755,13 @@ symbols! {
         u64,
         u8,
         unboxed_closures,
+        unchecked_add,
+        unchecked_div,
+        unchecked_mul,
+        unchecked_rem,
         unchecked_shl,
         unchecked_shr,
+        unchecked_sub,
         underscore_const_names,
         underscore_imports,
         underscore_lifetimes,