Skip to content

Commit 8cdc94e

Browse files
committed
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 rust-lang/miri#1074. The Miri-side patch is at rust-lang/miri#1513. r? @oli-obk
2 parents 67e7b9b + 6da8503 commit 8cdc94e

File tree

2 files changed

+23
-10
lines changed

2 files changed

+23
-10
lines changed

src/librustc_mir/interpret/machine.rs

+10
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ pub trait Machine<'mir, 'tcx>: Sized {
122122
/// Whether memory accesses should be alignment-checked.
123123
fn enforce_alignment(memory_extra: &Self::MemoryExtra) -> bool;
124124

125+
/// Whether, when checking alignment, we should `force_int` and thus support
126+
/// custom alignment logic based on whatever the integer address happens to be.
127+
fn force_int_for_alignment_check(memory_extra: &Self::MemoryExtra) -> bool;
128+
125129
/// Whether to enforce the validity invariant
126130
fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
127131

@@ -375,6 +379,12 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
375379
false
376380
}
377381

382+
#[inline(always)]
383+
fn force_int_for_alignment_check(_memory_extra: &Self::MemoryExtra) -> bool {
384+
// We do not support `force_int`.
385+
false
386+
}
387+
378388
#[inline(always)]
379389
fn enforce_validity(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
380390
false // for now, we don't enforce validity

src/librustc_mir/interpret/memory.rs

+13-10
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
99
use std::borrow::Cow;
1010
use std::collections::VecDeque;
11-
use std::convert::TryFrom;
11+
use std::convert::{TryFrom, TryInto};
1212
use std::fmt;
1313
use std::ptr;
1414

@@ -380,7 +380,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
380380
// if this is already a `Pointer` we want to do the bounds checks!
381381
sptr
382382
} else {
383-
// A "real" access, we must get a pointer.
383+
// A "real" access, we must get a pointer to be able to check the bounds.
384384
Scalar::from(self.force_ptr(sptr)?)
385385
};
386386
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> {
411411
// Test align. Check this last; if both bounds and alignment are violated
412412
// we want the error to be about the bounds.
413413
if let Some(align) = align {
414-
if alloc_align.bytes() < align.bytes() {
415-
// The allocation itself is not aligned enough.
416-
// FIXME: Alignment check is too strict, depending on the base address that
417-
// got picked we might be aligned even if this check fails.
418-
// We instead have to fall back to converting to an integer and checking
419-
// the "real" alignment.
420-
throw_ub!(AlignmentCheckFailed { has: alloc_align, required: align });
414+
if M::force_int_for_alignment_check(&self.extra) {
415+
let bits = self
416+
.force_bits(ptr.into(), self.pointer_size())
417+
.expect("ptr-to-int cast for align check should never fail");
418+
check_offset_align(bits.try_into().unwrap(), align)?;
419+
} else {
420+
// Check allocation alignment and offset alignment.
421+
if alloc_align.bytes() < align.bytes() {
422+
throw_ub!(AlignmentCheckFailed { has: alloc_align, required: align });
423+
}
424+
check_offset_align(ptr.offset.bytes(), align)?;
421425
}
422-
check_offset_align(ptr.offset.bytes(), align)?;
423426
}
424427

425428
// We can still be zero-sized in this branch, in which case we have to

0 commit comments

Comments
 (0)