Auto merge of #75592 - RalfJung:miri-int-align, r=oli-obk
miri engine: add option to use force_int for alignment check This is needed for https://github.com/rust-lang/miri/issues/1074. The Miri-side patch is at https://github.com/rust-lang/miri/pull/1513. r? @oli-obk
This commit is contained in:
commit
8cdc94e840
2 changed files with 23 additions and 10 deletions
|
@ -122,6 +122,10 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
||||||
/// Whether memory accesses should be alignment-checked.
|
/// Whether memory accesses should be alignment-checked.
|
||||||
fn enforce_alignment(memory_extra: &Self::MemoryExtra) -> bool;
|
fn enforce_alignment(memory_extra: &Self::MemoryExtra) -> bool;
|
||||||
|
|
||||||
|
/// Whether, when checking alignment, we should `force_int` and thus support
|
||||||
|
/// custom alignment logic based on whatever the integer address happens to be.
|
||||||
|
fn force_int_for_alignment_check(memory_extra: &Self::MemoryExtra) -> bool;
|
||||||
|
|
||||||
/// Whether to enforce the validity invariant
|
/// Whether to enforce the validity invariant
|
||||||
fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
|
fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
|
||||||
|
|
||||||
|
@ -375,6 +379,12 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn force_int_for_alignment_check(_memory_extra: &Self::MemoryExtra) -> bool {
|
||||||
|
// We do not support `force_int`.
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn enforce_validity(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
|
fn enforce_validity(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
|
||||||
false // for now, we don't enforce validity
|
false // for now, we don't enforce validity
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::convert::TryFrom;
|
use std::convert::{TryFrom, TryInto};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
|
@ -380,7 +380,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
||||||
// if this is already a `Pointer` we want to do the bounds checks!
|
// if this is already a `Pointer` we want to do the bounds checks!
|
||||||
sptr
|
sptr
|
||||||
} else {
|
} else {
|
||||||
// A "real" access, we must get a pointer.
|
// A "real" access, we must get a pointer to be able to check the bounds.
|
||||||
Scalar::from(self.force_ptr(sptr)?)
|
Scalar::from(self.force_ptr(sptr)?)
|
||||||
};
|
};
|
||||||
Ok(match normalized.to_bits_or_ptr(self.pointer_size(), self) {
|
Ok(match normalized.to_bits_or_ptr(self.pointer_size(), self) {
|
||||||
|
@ -411,15 +411,18 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
||||||
// Test align. Check this last; if both bounds and alignment are violated
|
// Test align. Check this last; if both bounds and alignment are violated
|
||||||
// we want the error to be about the bounds.
|
// we want the error to be about the bounds.
|
||||||
if let Some(align) = align {
|
if let Some(align) = align {
|
||||||
if alloc_align.bytes() < align.bytes() {
|
if M::force_int_for_alignment_check(&self.extra) {
|
||||||
// The allocation itself is not aligned enough.
|
let bits = self
|
||||||
// FIXME: Alignment check is too strict, depending on the base address that
|
.force_bits(ptr.into(), self.pointer_size())
|
||||||
// got picked we might be aligned even if this check fails.
|
.expect("ptr-to-int cast for align check should never fail");
|
||||||
// We instead have to fall back to converting to an integer and checking
|
check_offset_align(bits.try_into().unwrap(), align)?;
|
||||||
// the "real" alignment.
|
} else {
|
||||||
throw_ub!(AlignmentCheckFailed { has: alloc_align, required: align });
|
// Check allocation alignment and offset alignment.
|
||||||
|
if alloc_align.bytes() < align.bytes() {
|
||||||
|
throw_ub!(AlignmentCheckFailed { has: alloc_align, required: align });
|
||||||
|
}
|
||||||
|
check_offset_align(ptr.offset.bytes(), align)?;
|
||||||
}
|
}
|
||||||
check_offset_align(ptr.offset.bytes(), align)?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can still be zero-sized in this branch, in which case we have to
|
// We can still be zero-sized in this branch, in which case we have to
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue