diff --git a/src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs b/src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs new file mode 100644 index 00000000000..170bc6e1ed1 --- /dev/null +++ b/src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs @@ -0,0 +1,32 @@ +//@error-pattern: memory is uninitialized at [0x4..0x8] +//@normalize-stderr-test: "a[0-9]+" -> "ALLOC" +#![feature(strict_provenance)] + +// Test printing allocations that contain single-byte provenance. + +use std::alloc::{alloc, dealloc, Layout}; +use std::mem::{self, MaybeUninit}; +use std::slice::from_raw_parts; + +fn byte_with_provenance(val: u8, prov: *const T) -> MaybeUninit { + let ptr = prov.with_addr(val as usize); + let bytes: [MaybeUninit; mem::size_of::<*const ()>()] = unsafe { mem::transmute(ptr) }; + let lsb = if cfg!(target_endian = "little") { 0 } else { bytes.len() - 1 }; + bytes[lsb] +} + +fn main() { + let layout = Layout::from_size_align(16, 8).unwrap(); + unsafe { + let ptr = alloc(layout); + let ptr_raw = ptr.cast::>(); + *ptr_raw.add(0) = byte_with_provenance(0x42, &42u8); + *ptr.add(1) = 0x12; + *ptr.add(2) = 0x13; + *ptr_raw.add(3) = byte_with_provenance(0x43, &0u8); + let slice1 = from_raw_parts(ptr, 8); + let slice2 = from_raw_parts(ptr.add(8), 8); + drop(slice1.cmp(slice2)); + dealloc(ptr, layout); + } +} diff --git a/src/tools/miri/tests/fail/uninit_buffer_with_provenance.stderr b/src/tools/miri/tests/fail/uninit_buffer_with_provenance.stderr new file mode 100644 index 00000000000..715d76aa1c2 --- /dev/null +++ b/src/tools/miri/tests/fail/uninit_buffer_with_provenance.stderr @@ -0,0 +1,32 @@ +error: Undefined Behavior: reading memory at ALLOC[0x0..0x8], but memory is uninitialized at [0x4..0x8], and this operation requires initialized memory + --> RUSTLIB/core/src/slice/cmp.rs:LL:CC + | +LL | let mut order = unsafe { memcmp(left.as_ptr(), right.as_ptr(), len) as isize }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reading memory at ALLOC[0x0..0x8], but memory is uninitialized at [0x4..0x8], and 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 `::compare` at RUSTLIB/core/src/slice/cmp.rs:LL:CC + = note: inside `core::slice::cmp::::cmp` at RUSTLIB/core/src/slice/cmp.rs:LL:CC +note: inside `main` at $DIR/uninit_buffer_with_provenance.rs:LL:CC + --> $DIR/uninit_buffer_with_provenance.rs:LL:CC + | +LL | drop(slice1.cmp(slice2)); + | ^^^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +Uninitialized memory occurred at ALLOC[0x4..0x8], in this allocation: +ALLOC (Rust heap, size: 16, align: 8) { + ╾42[ALLOC] (1 ptr byte)╼ 12 13 ╾43[ALLOC] (1 ptr byte)╼ __ __ __ __ __ __ __ __ __ __ __ __ │ ━..━░░░░░░░░░░░░ +} +ALLOC (global (static or const), size: 1, align: 1) { + 2a │ * +} +ALLOC (global (static or const), size: 1, align: 1) { + 00 │ . +} + +error: aborting due to previous error +