diff options
| -rw-r--r-- | compiler/rustc_const_eval/src/const_eval/machine.rs | 39 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/machine.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/memory.rs | 41 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/const_prop.rs | 13 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/dataflow_const_prop.rs | 9 | ||||
| -rw-r--r-- | src/tools/miri/src/machine.rs | 11 |
6 files changed, 78 insertions, 44 deletions
diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 355ad669296..50776d65551 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -1,9 +1,10 @@ use rustc_hir::def::DefKind; -use rustc_hir::LangItem; +use rustc_hir::{LangItem, CRATE_HIR_ID}; use rustc_middle::mir; -use rustc_middle::mir::interpret::PointerArithmetic; +use rustc_middle::mir::interpret::{PointerArithmetic, UndefinedBehaviorInfo}; use rustc_middle::ty::layout::FnAbiOf; use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_session::lint::builtin::INVALID_ALIGNMENT; use std::borrow::Borrow; use std::hash::Hash; use std::ops::ControlFlow; @@ -338,6 +339,40 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, ecx.tcx.sess.opts.unstable_opts.extra_const_ub_checks } + fn alignment_check_failed( + ecx: &InterpCx<'mir, 'tcx, Self>, + has: Align, + required: Align, + check: CheckAlignment, + ) -> InterpResult<'tcx, ()> { + match check { + CheckAlignment::Error => { + throw_ub!(AlignmentCheckFailed { has, required }) + } + CheckAlignment::No => span_bug!( + ecx.cur_span(), + "`alignment_check_failed` called when no alignment check requested" + ), + CheckAlignment::FutureIncompat => ecx.tcx.struct_span_lint_hir( + INVALID_ALIGNMENT, + ecx.stack().iter().find_map(|frame| frame.lint_root()).unwrap_or(CRATE_HIR_ID), + ecx.cur_span(), + UndefinedBehaviorInfo::AlignmentCheckFailed { has, required }.to_string(), + |db| { + let mut stacktrace = ecx.generate_stacktrace(); + // Filter out `requires_caller_location` frames. + stacktrace + .retain(|frame| !frame.instance.def.requires_caller_location(*ecx.tcx)); + for frame in stacktrace { + db.span_label(frame.span, format!("inside `{}`", frame.instance)); + } + db + }, + ), + } + Ok(()) + } + fn load_mir( ecx: &InterpCx<'mir, 'tcx, Self>, instance: ty::InstanceDef<'tcx>, diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index f52545317ea..1d4ef20d065 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -10,7 +10,7 @@ use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_middle::mir; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::def_id::DefId; -use rustc_target::abi::Size; +use rustc_target::abi::{Align, Size}; use rustc_target::spec::abi::Abi as CallAbi; use crate::const_eval::CheckAlignment; @@ -132,6 +132,13 @@ pub trait Machine<'mir, 'tcx>: Sized { /// If this returns true, Provenance::OFFSET_IS_ADDR must be true. fn use_addr_for_alignment_check(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool; + fn alignment_check_failed( + ecx: &InterpCx<'mir, 'tcx, Self>, + has: Align, + required: Align, + check: CheckAlignment, + ) -> InterpResult<'tcx, ()>; + /// Whether to enforce the validity invariant fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool; diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index ffd5e05bcc4..5b1ac6b2f65 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -14,11 +14,8 @@ use std::ptr; use rustc_ast::Mutability; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_hir::CRATE_HIR_ID; use rustc_middle::mir::display_allocation; -use rustc_middle::mir::interpret::UndefinedBehaviorInfo; use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TyCtxt}; -use rustc_session::lint::builtin::INVALID_ALIGNMENT; use rustc_target::abi::{Align, HasDataLayout, Size}; use crate::const_eval::CheckAlignment; @@ -448,7 +445,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } else { // Check allocation alignment and offset alignment. if alloc_align.bytes() < align.bytes() { - self.alignment_check_failed(alloc_align, align, check)?; + M::alignment_check_failed(self, alloc_align, align, check)?; } self.check_offset_align(offset.bytes(), align, check)?; } @@ -472,43 +469,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } else { // The biggest power of two through which `offset` is divisible. let offset_pow2 = 1 << offset.trailing_zeros(); - self.alignment_check_failed(Align::from_bytes(offset_pow2).unwrap(), align, check) + M::alignment_check_failed(self, Align::from_bytes(offset_pow2).unwrap(), align, check) } } - - fn alignment_check_failed( - &self, - has: Align, - required: Align, - check: CheckAlignment, - ) -> InterpResult<'tcx, ()> { - match check { - CheckAlignment::Error => { - throw_ub!(AlignmentCheckFailed { has, required }) - } - CheckAlignment::No => span_bug!( - self.cur_span(), - "`alignment_check_failed` called when no alignment check requested" - ), - CheckAlignment::FutureIncompat => self.tcx.struct_span_lint_hir( - INVALID_ALIGNMENT, - self.stack().iter().find_map(|frame| frame.lint_root()).unwrap_or(CRATE_HIR_ID), - self.cur_span(), - UndefinedBehaviorInfo::AlignmentCheckFailed { has, required }.to_string(), - |db| { - let mut stacktrace = self.generate_stacktrace(); - // Filter out `requires_caller_location` frames. - stacktrace - .retain(|frame| !frame.instance.def.requires_caller_location(*self.tcx)); - for frame in stacktrace { - db.span_label(frame.span, format!("inside `{}`", frame.instance)); - } - db - }, - ), - } - Ok(()) - } } /// Allocation accessors diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index c8ba6310d59..044b7ce65bd 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -23,7 +23,7 @@ use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayo use rustc_middle::ty::InternalSubsts; use rustc_middle::ty::{self, ConstKind, Instance, ParamEnv, Ty, TyCtxt, TypeVisitable}; use rustc_span::{def_id::DefId, Span}; -use rustc_target::abi::{self, HasDataLayout, Size, TargetDataLayout}; +use rustc_target::abi::{self, Align, HasDataLayout, Size, TargetDataLayout}; use rustc_target::spec::abi::Abi as CallAbi; use rustc_trait_selection::traits; @@ -197,6 +197,17 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx> fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool { false // for now, we don't enforce validity } + fn alignment_check_failed( + ecx: &InterpCx<'mir, 'tcx, Self>, + _has: Align, + _required: Align, + _check: CheckAlignment, + ) -> InterpResult<'tcx, ()> { + span_bug!( + ecx.cur_span(), + "`alignment_check_failed` called when no alignment check requested" + ) + } fn load_mir( _ecx: &InterpCx<'mir, 'tcx, Self>, diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index 37675426f19..c75fe2327de 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -11,6 +11,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_mir_dataflow::value_analysis::{Map, State, TrackElem, ValueAnalysis, ValueOrPlace}; use rustc_mir_dataflow::{lattice::FlatSet, Analysis, ResultsVisitor, SwitchIntEdgeEffects}; use rustc_span::DUMMY_SP; +use rustc_target::abi::Align; use crate::MirPass; @@ -456,6 +457,14 @@ impl<'mir, 'tcx> rustc_const_eval::interpret::Machine<'mir, 'tcx> for DummyMachi fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool { unimplemented!() } + fn alignment_check_failed( + _ecx: &InterpCx<'mir, 'tcx, Self>, + _has: Align, + _required: Align, + _check: CheckAlignment, + ) -> interpret::InterpResult<'tcx, ()> { + unimplemented!() + } fn find_mir_or_eval_fn( _ecx: &mut InterpCx<'mir, 'tcx, Self>, diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 8f3c979f5eb..ab629e4711b 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -22,7 +22,7 @@ use rustc_middle::{ }; use rustc_span::def_id::{CrateNum, DefId}; use rustc_span::Symbol; -use rustc_target::abi::Size; +use rustc_target::abi::{Size, Align}; use rustc_target::spec::abi::Abi; use rustc_const_eval::const_eval::CheckAlignment; @@ -766,6 +766,15 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { ecx.machine.check_alignment == AlignmentCheck::Int } + fn alignment_check_failed( + _ecx: &InterpCx<'mir, 'tcx, Self>, + has: Align, + required: Align, + _check: CheckAlignment, + ) -> InterpResult<'tcx, ()> { + throw_ub!(AlignmentCheckFailed { has, required }) + } + #[inline(always)] fn enforce_validity(ecx: &MiriInterpCx<'mir, 'tcx>) -> bool { ecx.machine.validate |
