From 28e6b1a60262b494c8e2869648f74d0dd0ebd0c7 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 13 Apr 2020 17:59:12 +0200 Subject: [PATCH] Miri: let machine hook dynamically decide about alignment checks --- src/librustc_mir/const_eval/machine.rs | 9 ++++++--- src/librustc_mir/interpret/machine.rs | 2 +- src/librustc_mir/interpret/memory.rs | 4 ++-- src/librustc_mir/transform/const_prop.rs | 5 ++++- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/librustc_mir/const_eval/machine.rs b/src/librustc_mir/const_eval/machine.rs index e926347147894..3f9aa9ed02d2a 100644 --- a/src/librustc_mir/const_eval/machine.rs +++ b/src/librustc_mir/const_eval/machine.rs @@ -179,9 +179,12 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter { const GLOBAL_KIND: Option = None; // no copying of globals from `tcx` to machine memory - // We do not check for alignment to avoid having to carry an `Align` - // in `ConstValue::ByRef`. - const CHECK_ALIGN: bool = false; + #[inline(always)] + fn enforce_alignment(_memory_extra: &Self::MemoryExtra) -> bool { + // We do not check for alignment to avoid having to carry an `Align` + // in `ConstValue::ByRef`. + false + } #[inline(always)] fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool { diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs index fd67b088c93cf..dd3803eb96255 100644 --- a/src/librustc_mir/interpret/machine.rs +++ b/src/librustc_mir/interpret/machine.rs @@ -118,7 +118,7 @@ pub trait Machine<'mir, 'tcx>: Sized { const GLOBAL_KIND: Option; /// Whether memory accesses should be alignment-checked. - const CHECK_ALIGN: bool; + fn enforce_alignment(memory_extra: &Self::MemoryExtra) -> bool; /// Whether to enforce the validity invariant fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool; diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 539537e9de80c..bcad7855c3736 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -323,12 +323,12 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { size: Size, align: Align, ) -> InterpResult<'tcx, Option>> { - let align = M::CHECK_ALIGN.then_some(align); + let align = M::enforce_alignment(&self.extra).then_some(align); self.check_ptr_access_align(sptr, size, align, CheckInAllocMsg::MemoryAccessTest) } /// Like `check_ptr_access`, but *definitely* checks alignment when `align` - /// is `Some` (overriding `M::CHECK_ALIGN`). Also lets the caller control + /// is `Some` (overriding `M::enforce_alignment`). Also lets the caller control /// the error message for the out-of-bounds case. pub fn check_ptr_access_align( &self, diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 5a00f206a7646..9a6d5ab34a5ac 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -173,7 +173,10 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine { const GLOBAL_KIND: Option = None; // no copying of globals from `tcx` to machine memory - const CHECK_ALIGN: bool = false; + #[inline(always)] + fn enforce_alignment(_memory_extra: &Self::MemoryExtra) -> bool { + false + } #[inline(always)] fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {