Skip to content

Commit

Permalink
fix UB in a test
Browse files Browse the repository at this point in the history
also add an explicit test for the fact that a Option<WidePtr> has padding when it is None
  • Loading branch information
RalfJung committed Sep 9, 2024
1 parent 65c7090 commit 0a70924
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 3 deletions.
7 changes: 6 additions & 1 deletion library/core/tests/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -773,15 +773,20 @@ fn offset_of_addr() {
#[test]
fn const_maybe_uninit_zeroed() {
// Sanity check for `MaybeUninit::zeroed` in a realistic const situation (plugin array term)

// It is crucial that this type has no padding!
#[repr(C)]
struct Foo {
a: Option<&'static str>,
a: Option<&'static u8>,
b: Bar,
c: f32,
_pad: u32,
d: *const u8,
}

#[repr(C)]
struct Bar(usize);

struct FooPtr(*const Foo);
unsafe impl Sync for FooPtr {}

Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/tests/fail/uninit/padding-enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ fn main() { unsafe {
// Turns out the discriminant is (currently) stored
// in the 2nd pointer, so the first half is padding.
let c = &p as *const _ as *const u8;
let _val = *c.add(0); // Get the padding byte.
let _val = *c.add(0); // Get a padding byte.
//~^ERROR: uninitialized
} }
2 changes: 1 addition & 1 deletion src/tools/miri/tests/fail/uninit/padding-enum.stderr
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory
--> $DIR/padding-enum.rs:LL:CC
|
LL | let _val = *c.add(0); // Get the padding byte.
LL | let _val = *c.add(0); // Get a padding byte.
| ^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
Expand Down
18 changes: 18 additions & 0 deletions src/tools/miri/tests/fail/uninit/padding-wide-ptr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use std::mem;

// If this is `None`, the metadata becomes padding.
type T = Option<&'static str>;

fn main() { unsafe {
let mut p: mem::MaybeUninit<T> = mem::MaybeUninit::zeroed();
// The copy when `T` is returned from `transmute` should destroy padding
// (even when we use `write_unaligned`, which under the hood uses an untyped copy).
p.as_mut_ptr().write_unaligned(mem::transmute((0usize, 0usize)));
// Null epresents `None`.
assert!(matches!(*p.as_ptr(), None));

// The second part, with the length, becomes padding.
let c = &p as *const _ as *const u8;
let _val = *c.add(mem::size_of::<*const u8>()); // Get a padding byte.
//~^ERROR: uninitialized
} }
15 changes: 15 additions & 0 deletions src/tools/miri/tests/fail/uninit/padding-wide-ptr.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory
--> $DIR/padding-wide-ptr.rs:LL:CC
|
LL | let _val = *c.add(mem::size_of::<*const u8>()); // Get a padding byte.
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
= 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 `main` at $DIR/padding-wide-ptr.rs:LL:CC

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

error: aborting due to 1 previous error

0 comments on commit 0a70924

Please sign in to comment.