about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2023-04-28 13:35:50 +0200
committerRalf Jung <post@ralfj.de>2023-04-28 16:00:08 +0200
commit586d17d330fa320deb1c2d738fb90d1235a7ade1 (patch)
treebc6c7b8b3235b5fa908df1da031af02075bff5ef
parent8b8110e1469d459a196f6feb60d82dec48c3cfc2 (diff)
downloadrust-586d17d330fa320deb1c2d738fb90d1235a7ade1.tar.gz
rust-586d17d330fa320deb1c2d738fb90d1235a7ade1.zip
share BinOp::Offset between CTFE and Miri
-rw-r--r--compiler/rustc_const_eval/src/const_eval/machine.rs17
-rw-r--r--compiler/rustc_const_eval/src/interpret/operator.rs26
-rw-r--r--src/tools/miri/src/operator.rs11
3 files changed, 29 insertions, 25 deletions
diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs
index bfca58a15b3..814b67b46ec 100644
--- a/compiler/rustc_const_eval/src/const_eval/machine.rs
+++ b/compiler/rustc_const_eval/src/const_eval/machine.rs
@@ -559,20 +559,11 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
     }
 
     fn binary_ptr_op(
-        ecx: &InterpCx<'mir, 'tcx, Self>,
-        bin_op: mir::BinOp,
-        left: &ImmTy<'tcx>,
-        right: &ImmTy<'tcx>,
+        _ecx: &InterpCx<'mir, 'tcx, Self>,
+        _bin_op: mir::BinOp,
+        _left: &ImmTy<'tcx>,
+        _right: &ImmTy<'tcx>,
     ) -> InterpResult<'tcx, (Scalar, bool, Ty<'tcx>)> {
-        if bin_op == mir::BinOp::Offset {
-            let ptr = left.to_scalar().to_pointer(ecx)?;
-            let offset_count = right.to_scalar().to_target_isize(ecx)?;
-            let pointee_ty = left.layout.ty.builtin_deref(true).unwrap().ty;
-
-            let offset_ptr = ecx.ptr_offset_inbounds(ptr, pointee_ty, offset_count)?;
-            return Ok((Scalar::from_maybe_pointer(offset_ptr, ecx), false, left.layout.ty));
-        }
-
         throw_unsup_format!("pointer arithmetic or comparison is not supported at compile-time");
     }
 
diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs
index 4decfe863e6..7186148daf0 100644
--- a/compiler/rustc_const_eval/src/interpret/operator.rs
+++ b/compiler/rustc_const_eval/src/interpret/operator.rs
@@ -299,6 +299,30 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         Ok((val, false, ty))
     }
 
+    fn binary_ptr_op(
+        &self,
+        bin_op: mir::BinOp,
+        left: &ImmTy<'tcx, M::Provenance>,
+        right: &ImmTy<'tcx, M::Provenance>,
+    ) -> InterpResult<'tcx, (Scalar<M::Provenance>, bool, Ty<'tcx>)> {
+        use rustc_middle::mir::BinOp::*;
+
+        match bin_op {
+            // Pointer ops that are always supported.
+            Offset => {
+                let ptr = left.to_scalar().to_pointer(self)?;
+                let offset_count = right.to_scalar().to_target_isize(self)?;
+                let pointee_ty = left.layout.ty.builtin_deref(true).unwrap().ty;
+
+                let offset_ptr = self.ptr_offset_inbounds(ptr, pointee_ty, offset_count)?;
+                Ok((Scalar::from_maybe_pointer(offset_ptr, self), false, left.layout.ty))
+            }
+
+            // Fall back to machine hook so Miri can support more pointer ops.
+            _ => M::binary_ptr_op(self, bin_op, left, right),
+        }
+    }
+
     /// Returns the result of the specified operation, whether it overflowed, and
     /// the result type.
     pub fn overflowing_binary_op(
@@ -368,7 +392,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     right.layout.ty
                 );
 
-                M::binary_ptr_op(self, bin_op, left, right)
+                self.binary_ptr_op(bin_op, left, right)
             }
             _ => span_bug!(
                 self.cur_span(),
diff --git a/src/tools/miri/src/operator.rs b/src/tools/miri/src/operator.rs
index 79d5dfb5551..368aa2bacdc 100644
--- a/src/tools/miri/src/operator.rs
+++ b/src/tools/miri/src/operator.rs
@@ -53,17 +53,6 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriInterpCx<'mir, 'tcx> {
                 (Scalar::from_bool(res), false, self.tcx.types.bool)
             }
 
-            Offset => {
-                assert!(left.layout.ty.is_unsafe_ptr());
-                let ptr = left.to_scalar().to_pointer(self)?;
-                let offset = right.to_scalar().to_target_isize(self)?;
-
-                let pointee_ty =
-                    left.layout.ty.builtin_deref(true).expect("Offset called on non-ptr type").ty;
-                let ptr = self.ptr_offset_inbounds(ptr, pointee_ty, offset)?;
-                (Scalar::from_maybe_pointer(ptr, self), false, left.layout.ty)
-            }
-
             // Some more operations are possible with atomics.
             // The return value always has the provenance of the *left* operand.
             Add | Sub | BitOr | BitAnd | BitXor => {