Skip to content

Commit ddcf94c

Browse files
Fix Miri symbolic alignment check failures (#2798)
* Fix Miri symbolic alignment check failures This change introduces the `miri_promise_symbolic_alignment` intrinsic and uses it to resolve false positives in Miri's symbolic alignment checking. This prepares the codebase for enabling `-Zmiri-symbolic-alignment-check` in CI. * Defined `miri_promise_symbolic_alignment` in `src/util/mod.rs` (guarded by `cfg(miri)`). * Applied the intrinsic in `src/pointer/ptr.rs` (`as_ref` and `as_mut`) to promise alignment when the `Aligned` invariant is held. * Enabled `feature(layout_for_ptr)` under Miri to allow using `align_of_val_raw` for unsized types. Note: The CI configuration (`.github/workflows/ci.yml`) must be updated separately to add `-Zmiri-symbolic-alignment-check` to `ZC_NIGHTLY_MIRIFLAGS`, as workflow modifications are restricted in this environment. Makes progress on #674 * Fix Miri symbolic alignment check failures This change introduces the `miri_promise_symbolic_alignment` intrinsic and uses it to resolve false positives in Miri's symbolic alignment checking. This prepares the codebase for enabling `-Zmiri-symbolic-alignment-check` in CI. * Defined `miri_promise_symbolic_alignment` in `src/util/mod.rs` (guarded by `cfg(miri)`). * Applied the intrinsic in `src/pointer/ptr.rs` (`as_ref` and `as_mut`) to promise alignment when the `Aligned` invariant is held. * Enabled `feature(layout_for_ptr)` under Miri to allow using `align_of_val_raw` for unsized types. Note: The CI configuration (`.github/workflows/ci.yml`) must be updated separately to add `-Zmiri-symbolic-alignment-check` to `ZC_NIGHTLY_MIRIFLAGS`, as workflow modifications are restricted in this environment. Makes progress on #674 --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
1 parent a9e527a commit ddcf94c

File tree

3 files changed

+34
-2
lines changed

3 files changed

+34
-2
lines changed

src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,9 +314,10 @@
314314
)]
315315
#![cfg_attr(feature = "float-nightly", feature(f16, f128))]
316316
#![cfg_attr(doc_cfg, feature(doc_cfg))]
317+
#![cfg_attr(__ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS, feature(coverage_attribute))]
317318
#![cfg_attr(
318-
__ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS,
319-
feature(layout_for_ptr, coverage_attribute)
319+
any(__ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS, miri),
320+
feature(layout_for_ptr)
320321
)]
321322

322323
// This is a hack to allow zerocopy-derive derives to work in this crate. They

src/pointer/ptr.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,15 @@ mod _conversions {
229229
#[allow(clippy::wrong_self_convention)]
230230
pub(crate) fn as_ref(self) -> &'a T {
231231
let raw = self.as_inner().as_non_null();
232+
// SAFETY: `self` satisfies the `Aligned` invariant, so we know that
233+
// `raw` is validly-aligned for `T`.
234+
#[cfg(miri)]
235+
unsafe {
236+
crate::util::miri_promise_symbolic_alignment(
237+
raw.as_ptr().cast(),
238+
core::mem::align_of_val_raw(raw.as_ptr()),
239+
);
240+
}
232241
// SAFETY: This invocation of `NonNull::as_ref` satisfies its
233242
// documented safety preconditions:
234243
//
@@ -323,6 +332,15 @@ mod _conversions {
323332
#[allow(clippy::wrong_self_convention)]
324333
pub(crate) fn as_mut(self) -> &'a mut T {
325334
let mut raw = self.as_inner().as_non_null();
335+
// SAFETY: `self` satisfies the `Aligned` invariant, so we know that
336+
// `raw` is validly-aligned for `T`.
337+
#[cfg(miri)]
338+
unsafe {
339+
crate::util::miri_promise_symbolic_alignment(
340+
raw.as_ptr().cast(),
341+
core::mem::align_of_val_raw(raw.as_ptr()),
342+
);
343+
}
326344
// SAFETY: This invocation of `NonNull::as_mut` satisfies its
327345
// documented safety preconditions:
328346
//

src/util/mod.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,19 @@ impl<T: ?Sized> Clone for SendSyncPhantomData<T> {
5252
}
5353
}
5454

55+
#[cfg(miri)]
56+
extern "Rust" {
57+
/// Miri-provided intrinsic that marks the pointer `ptr` as aligned to
58+
/// `align`.
59+
///
60+
/// This intrinsic is used to inform Miri's symbolic alignment checker that
61+
/// a pointer is aligned, even if Miri cannot statically deduce that fact.
62+
/// This is often required when performing raw pointer arithmetic or casts
63+
/// where the alignment is guaranteed by runtime checks or invariants that
64+
/// Miri is not aware of.
65+
pub(crate) fn miri_promise_symbolic_alignment(ptr: *const (), align: usize);
66+
}
67+
5568
pub(crate) trait AsAddress {
5669
fn addr(self) -> usize;
5770
}

0 commit comments

Comments
 (0)