Skip to content

Commit

Permalink
Auto merge of rust-lang#3001 - RalfJung:align, r=RalfJung
Browse files Browse the repository at this point in the history
add some interesting tests for alignment corner cases

`strange_enum_discriminant_offset` example found in rust-lang#53998.
  • Loading branch information
bors committed Jul 31, 2023
2 parents e1071af + a63db6d commit 10d77b9
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/// This tests that when a field sits at offset 0 in a 4-aligned struct, accessing the field
/// requires alignment 4 even if the field type has lower alignment requirements.

#[repr(C)]
pub struct S {
x: u8,
y: u32,
}

unsafe fn foo(x: *const S) -> u8 {
unsafe { (*x).x } //~ERROR: accessing memory with alignment 1, but alignment 4 is required
}

fn main() {
unsafe {
let mem = [0u64; 16];
let odd_ptr = std::ptr::addr_of!(mem).cast::<u8>().add(1);
// `odd_ptr` is now not aligned enough for `S`.
// If accessing field `x` can exploit that it is at offset 0
// in a 4-aligned struct, that field access requires alignment 4,
// thus making this UB.
foo(odd_ptr.cast());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required
--> $DIR/field_requires_parent_struct_alignment.rs:LL:CC
|
LL | unsafe { (*x).x }
| ^^^^^^ accessing memory with alignment ALIGN, but alignment ALIGN is required
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: BACKTRACE:
= note: inside `foo` at $DIR/field_requires_parent_struct_alignment.rs:LL:CC
note: inside `main`
--> $DIR/field_requires_parent_struct_alignment.rs:LL:CC
|
LL | foo(odd_ptr.cast());
| ^^^^^^^^^^^^^^^^^^^

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

error: aborting due to previous error

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#![allow(unused)]

#[repr(u16)]
enum DeviceKind {
Nil = 0,
}

#[repr(C, packed)]
struct DeviceInfo {
endianness: u8,
device_kind: DeviceKind,
}

fn main() {
// The layout of `Option<(DeviceInfo, u64)>` is funny: it uses the
// `DeviceKind` enum as niche, so that is offset 1, but the niche type is u16!
// So despite the type having alignment 8 and the field type alignment 2,
// the actual alignment is 1.
let x = None::<(DeviceInfo, u8)>;
let y = None::<(DeviceInfo, u16)>;
let z = None::<(DeviceInfo, u64)>;
format!("{} {} {}", x.is_some(), y.is_some(), y.is_some());
}
18 changes: 0 additions & 18 deletions src/tools/miri/tests/pass/issues/issue-53728.rs

This file was deleted.

0 comments on commit 10d77b9

Please sign in to comment.