Skip to content

Commit

Permalink
move calling miri_promise_symbolic_alignment to a shared helper
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Dec 3, 2023
1 parent bebba4f commit 2a3fcc0
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 65 deletions.
25 changes: 25 additions & 0 deletions library/core/src/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2859,3 +2859,28 @@ pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
write_bytes(dst, val, count)
}
}

/// Inform Miri that a given pointer definitely has a certain alignment.
#[cfg(miri)]
pub(crate) const fn miri_promise_symbolic_alignment(ptr: *const (), align: usize) {
extern "Rust" {
/// Miri-provided extern function to promise that a given pointer is properly aligned for
/// "symbolic" alignment checks. Will fail if the pointer is not actually aligned or `align` is
/// not a power of two. Has no effect when alignment checks are concrete (which is the default).
fn miri_promise_symbolic_alignment(ptr: *const (), align: usize);
}

fn runtime(ptr: *const (), align: usize) {
// SAFETY: this call is always safe.
unsafe {
miri_promise_symbolic_alignment(ptr, align);
}
}

const fn compiletime(_ptr: *const (), _align: usize) {}

// SAFETY: the extra behavior at runtime is for UB checks only.
unsafe {
const_eval_select((ptr, align), compiletime, runtime);
}
}
22 changes: 1 addition & 21 deletions library/core/src/ptr/const_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1374,27 +1374,7 @@ impl<T: ?Sized> *const T {
// Inform Miri that we want to consider the resulting pointer to be suitably aligned.
#[cfg(miri)]
if ret != usize::MAX {
fn runtime(ptr: *const (), align: usize) {
extern "Rust" {
pub fn miri_promise_symbolic_alignment(ptr: *const (), align: usize);
}

// SAFETY: this call is always safe.
unsafe {
miri_promise_symbolic_alignment(ptr, align);
}
}

const fn compiletime(_ptr: *const (), _align: usize) {}

// SAFETY: the extra behavior at runtime is for UB checks only.
unsafe {
intrinsics::const_eval_select(
(self.wrapping_add(ret).cast(), align),
compiletime,
runtime,
);
}
intrinsics::miri_promise_symbolic_alignment(self.wrapping_add(ret).cast(), align);
}

ret
Expand Down
25 changes: 4 additions & 21 deletions library/core/src/ptr/mut_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1641,27 +1641,10 @@ impl<T: ?Sized> *mut T {
// Inform Miri that we want to consider the resulting pointer to be suitably aligned.
#[cfg(miri)]
if ret != usize::MAX {
fn runtime(ptr: *const (), align: usize) {
extern "Rust" {
pub fn miri_promise_symbolic_alignment(ptr: *const (), align: usize);
}

// SAFETY: this call is always safe.
unsafe {
miri_promise_symbolic_alignment(ptr, align);
}
}

const fn compiletime(_ptr: *const (), _align: usize) {}

// SAFETY: the extra behavior at runtime is for UB checks only.
unsafe {
intrinsics::const_eval_select(
(self.wrapping_add(ret).cast_const().cast(), align),
compiletime,
runtime,
);
}
intrinsics::miri_promise_symbolic_alignment(
self.wrapping_add(ret).cast_const().cast(),
align,
);
}

ret
Expand Down
31 changes: 8 additions & 23 deletions library/core/src/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3870,16 +3870,10 @@ impl<T> [T] {
let (us_len, ts_len) = rest.align_to_offsets::<U>();
// Inform Miri that we want to consider the "middle" pointer to be suitably aligned.
#[cfg(miri)]
{
extern "Rust" {
pub fn miri_promise_symbolic_alignment(ptr: *const (), align: usize);
}

// SAFETY: this call is always safe.
unsafe {
miri_promise_symbolic_alignment(rest.as_ptr().cast(), mem::align_of::<U>());
}
}
crate::intrinsics::miri_promise_symbolic_alignment(
rest.as_ptr().cast(),
mem::align_of::<U>(),
);
// SAFETY: now `rest` is definitely aligned, so `from_raw_parts` below is okay,
// since the caller guarantees that we can transmute `T` to `U` safely.
unsafe {
Expand Down Expand Up @@ -3952,19 +3946,10 @@ impl<T> [T] {
let mut_ptr = rest.as_mut_ptr();
// Inform Miri that we want to consider the "middle" pointer to be suitably aligned.
#[cfg(miri)]
{
extern "Rust" {
pub fn miri_promise_symbolic_alignment(ptr: *const (), align: usize);
}

// SAFETY: this call is always safe.
unsafe {
miri_promise_symbolic_alignment(
mut_ptr.cast() as *const (),
mem::align_of::<U>(),
);
}
}
crate::intrinsics::miri_promise_symbolic_alignment(
mut_ptr.cast() as *const (),
mem::align_of::<U>(),
);
// We can't use `rest` again after this, that would invalidate its alias `mut_ptr`!
// SAFETY: see comments for `align_to`.
unsafe {
Expand Down

0 comments on commit 2a3fcc0

Please sign in to comment.