about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2024-09-09 16:11:17 +0200
committerRalf Jung <post@ralfj.de>2024-09-09 16:17:34 +0200
commit0a70924c2160c8f93a446328e207a1983e62596a (patch)
tree1083231c0279ae34c9f71ad765b7b5bbe009c55a
parent65c70900ceda1c276c8eef1dad4e2c4f7a0756d0 (diff)
downloadrust-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.rs7
-rw-r--r--src/tools/miri/tests/fail/uninit/padding-enum.rs2
-rw-r--r--src/tools/miri/tests/fail/uninit/padding-enum.stderr2
-rw-r--r--src/tools/miri/tests/fail/uninit/padding-wide-ptr.rs18
-rw-r--r--src/tools/miri/tests/fail/uninit/padding-wide-ptr.stderr15
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
+