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;
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>,
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;
/// 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;
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;
} 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)?;
}
} 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
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;
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>,
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;
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>,
};
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;
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