diff options
| author | Ralf Jung <post@ralfj.de> | 2023-04-28 13:35:50 +0200 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2023-04-28 16:00:08 +0200 |
| commit | 586d17d330fa320deb1c2d738fb90d1235a7ade1 (patch) | |
| tree | bc6c7b8b3235b5fa908df1da031af02075bff5ef | |
| parent | 8b8110e1469d459a196f6feb60d82dec48c3cfc2 (diff) | |
| download | rust-586d17d330fa320deb1c2d738fb90d1235a7ade1.tar.gz rust-586d17d330fa320deb1c2d738fb90d1235a7ade1.zip | |
share BinOp::Offset between CTFE and Miri
| -rw-r--r-- | compiler/rustc_const_eval/src/const_eval/machine.rs | 17 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/operator.rs | 26 | ||||
| -rw-r--r-- | src/tools/miri/src/operator.rs | 11 |
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 => { |
