miri: support 'promising' alignment for symbolic alignment check
This commit is contained in:
parent
7ceaf19868
commit
bebba4f6e0
14 changed files with 298 additions and 118 deletions
|
@ -12,12 +12,12 @@ use rustc_middle::mir;
|
|||
use rustc_middle::ty::layout::TyAndLayout;
|
||||
use rustc_middle::ty::{self, 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 super::{
|
||||
AllocBytes, AllocId, AllocRange, Allocation, ConstAllocation, FnArg, Frame, ImmTy, InterpCx,
|
||||
InterpResult, MPlaceTy, MemoryKind, OpTy, PlaceTy, Pointer, Provenance,
|
||||
AllocBytes, AllocId, AllocKind, AllocRange, Allocation, ConstAllocation, FnArg, Frame, ImmTy,
|
||||
InterpCx, InterpResult, MPlaceTy, MemoryKind, Misalignment, OpTy, PlaceTy, Pointer, Provenance,
|
||||
};
|
||||
|
||||
/// Data returned by Machine::stack_pop,
|
||||
|
@ -143,11 +143,18 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
|
|||
/// Whether memory accesses should be alignment-checked.
|
||||
fn enforce_alignment(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
|
||||
|
||||
/// Whether, when checking alignment, we should look at the actual address and thus support
|
||||
/// custom alignment logic based on whatever the integer address happens to be.
|
||||
///
|
||||
/// If this returns true, Provenance::OFFSET_IS_ADDR must be true.
|
||||
fn use_addr_for_alignment_check(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
|
||||
/// Gives the machine a chance to detect more misalignment than the built-in checks would catch.
|
||||
#[inline(always)]
|
||||
fn alignment_check(
|
||||
_ecx: &InterpCx<'mir, 'tcx, Self>,
|
||||
_alloc_id: AllocId,
|
||||
_alloc_align: Align,
|
||||
_alloc_kind: AllocKind,
|
||||
_offset: Size,
|
||||
_align: Align,
|
||||
) -> Option<Misalignment> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Whether to enforce the validity invariant for a specific layout.
|
||||
fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>, layout: TyAndLayout<'tcx>) -> bool;
|
||||
|
@ -519,12 +526,6 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
|
|||
type FrameExtra = ();
|
||||
type Bytes = Box<[u8]>;
|
||||
|
||||
#[inline(always)]
|
||||
fn use_addr_for_alignment_check(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
|
||||
// We do not support `use_addr`.
|
||||
false
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn ignore_optional_overflow_checks(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
|
||||
false
|
||||
|
|
|
@ -58,6 +58,7 @@ impl<T: fmt::Display> fmt::Display for MemoryKind<T> {
|
|||
}
|
||||
|
||||
/// The return value of `get_alloc_info` indicates the "kind" of the allocation.
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum AllocKind {
|
||||
/// A regular live data allocation.
|
||||
LiveData,
|
||||
|
@ -473,8 +474,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
match self.ptr_try_get_alloc_id(ptr) {
|
||||
Err(addr) => offset_misalignment(addr, align),
|
||||
Ok((alloc_id, offset, _prov)) => {
|
||||
let (_size, alloc_align, _kind) = self.get_alloc_info(alloc_id);
|
||||
if M::use_addr_for_alignment_check(self) {
|
||||
let (_size, alloc_align, kind) = self.get_alloc_info(alloc_id);
|
||||
if let Some(misalign) =
|
||||
M::alignment_check(self, alloc_id, alloc_align, kind, offset, align)
|
||||
{
|
||||
Some(misalign)
|
||||
} else if M::Provenance::OFFSET_IS_ADDR {
|
||||
// `use_addr_for_alignment_check` can only be true if `OFFSET_IS_ADDR` is true.
|
||||
offset_misalignment(ptr.addr().bytes(), align)
|
||||
} else {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue