about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2023-11-20 08:22:56 +0100
committerRalf Jung <post@ralfj.de>2023-12-03 21:51:14 +0100
commit2a3fcc0a57d620f09207ab76671709eba8af8559 (patch)
treeb02c077099770f10873f9960878431f3fe5c790d
parentbebba4f6e05fae60ce8dcddc5eb6b4e7686bd995 (diff)
downloadrust-2a3fcc0a57d620f09207ab76671709eba8af8559.tar.gz
rust-2a3fcc0a57d620f09207ab76671709eba8af8559.zip
move calling miri_promise_symbolic_alignment to a shared helper
-rw-r--r--library/core/src/intrinsics.rs25
-rw-r--r--library/core/src/ptr/const_ptr.rs22
-rw-r--r--library/core/src/ptr/mut_ptr.rs25
-rw-r--r--library/core/src/slice/mod.rs31
4 files changed, 38 insertions, 65 deletions
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index 214c8e49a5a..ab86e4e39ea 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -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);
+    }
+}
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index 46e8676162a..2f47ca29ec5 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -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
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 3f44d78795b..3aaae679a6f 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -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
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 7d88f70efd1..5957f9fd443 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -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 {
@@ -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 {