fix UB in a test

also add an explicit test for the fact that a Option<WidePtr> has padding when it is None
This commit is contained in:
Ralf Jung 2024-09-09 16:11:17 +02:00
parent 65c70900ce
commit 0a70924c21
5 changed files with 41 additions and 3 deletions

View File

@ -773,15 +773,20 @@ struct Foo {
#[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 {}

View File

@ -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
} }

View File

@ -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

View File

@ -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
} }

View File

@ -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