diff options
| author | Ralf Jung <post@ralfj.de> | 2024-09-09 16:11:17 +0200 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2024-09-09 16:17:34 +0200 |
| commit | 0a70924c2160c8f93a446328e207a1983e62596a (patch) | |
| tree | 1083231c0279ae34c9f71ad765b7b5bbe009c55a | |
| parent | 65c70900ceda1c276c8eef1dad4e2c4f7a0756d0 (diff) | |
| download | rust-0a70924c2160c8f93a446328e207a1983e62596a.tar.gz rust-0a70924c2160c8f93a446328e207a1983e62596a.zip | |
fix UB in a test
also add an explicit test for the fact that a Option<WidePtr> has padding when it is None
| -rw-r--r-- | library/core/tests/mem.rs | 7 | ||||
| -rw-r--r-- | src/tools/miri/tests/fail/uninit/padding-enum.rs | 2 | ||||
| -rw-r--r-- | src/tools/miri/tests/fail/uninit/padding-enum.stderr | 2 | ||||
| -rw-r--r-- | src/tools/miri/tests/fail/uninit/padding-wide-ptr.rs | 18 | ||||
| -rw-r--r-- | src/tools/miri/tests/fail/uninit/padding-wide-ptr.stderr | 15 |
5 files changed, 41 insertions, 3 deletions
diff --git a/library/core/tests/mem.rs b/library/core/tests/mem.rs index b7eee10ec3f..f3b4387f6a8 100644 --- a/library/core/tests/mem.rs +++ b/library/core/tests/mem.rs @@ -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 {} diff --git a/src/tools/miri/tests/fail/uninit/padding-enum.rs b/src/tools/miri/tests/fail/uninit/padding-enum.rs index 0ab9be27581..3852ac5c477 100644 --- a/src/tools/miri/tests/fail/uninit/padding-enum.rs +++ b/src/tools/miri/tests/fail/uninit/padding-enum.rs @@ -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 } } diff --git a/src/tools/miri/tests/fail/uninit/padding-enum.stderr b/src/tools/miri/tests/fail/uninit/padding-enum.stderr index a507a5d49bc..c571f188740 100644 --- a/src/tools/miri/tests/fail/uninit/padding-enum.stderr +++ b/src/tools/miri/tests/fail/uninit/padding-enum.stderr @@ -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 diff --git a/src/tools/miri/tests/fail/uninit/padding-wide-ptr.rs b/src/tools/miri/tests/fail/uninit/padding-wide-ptr.rs new file mode 100644 index 00000000000..0403a9caba6 --- /dev/null +++ b/src/tools/miri/tests/fail/uninit/padding-wide-ptr.rs @@ -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 +} } diff --git a/src/tools/miri/tests/fail/uninit/padding-wide-ptr.stderr b/src/tools/miri/tests/fail/uninit/padding-wide-ptr.stderr new file mode 100644 index 00000000000..0da72550b2e --- /dev/null +++ b/src/tools/miri/tests/fail/uninit/padding-wide-ptr.stderr @@ -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 + |
