about summary refs log tree commit diff
path: root/src/tools/miri/tests/fail
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-08-07 07:25:51 +0000
committerbors <bors@rust-lang.org>2023-08-07 07:25:51 +0000
commitadb15a20ac99024ea90b28abd5af12f438fa2a20 (patch)
tree6c0e939fc6371f2175539ee517f00e1c8d57fbd9 /src/tools/miri/tests/fail
parent4a71a05d52a534c18fed8b1415c4858570d8ef86 (diff)
parentd1174a974e97017de75a33e7b878e13acdd3d5d5 (diff)
downloadrust-adb15a20ac99024ea90b28abd5af12f438fa2a20.tar.gz
rust-adb15a20ac99024ea90b28abd5af12f438fa2a20.zip
Auto merge of #114560 - RalfJung:miri, r=RalfJung
update Miri
Diffstat (limited to 'src/tools/miri/tests/fail')
-rw-r--r--src/tools/miri/tests/fail/both_borrows/retag_data_race_protected_read.rs29
-rw-r--r--src/tools/miri/tests/fail/both_borrows/retag_data_race_protected_read.stack.stderr20
-rw-r--r--src/tools/miri/tests/fail/both_borrows/retag_data_race_protected_read.tree.stderr25
-rw-r--r--src/tools/miri/tests/fail/both_borrows/retag_data_race_write.rs (renamed from src/tools/miri/tests/fail/stacked_borrows/retag_data_race_write.rs)4
-rw-r--r--src/tools/miri/tests/fail/both_borrows/retag_data_race_write.stack.stderr (renamed from src/tools/miri/tests/fail/stacked_borrows/retag_data_race_write.stderr)0
-rw-r--r--src/tools/miri/tests/fail/both_borrows/retag_data_race_write.tree.stderr25
-rw-r--r--src/tools/miri/tests/fail/function_calls/return_pointer_aliasing2.rs30
-rw-r--r--src/tools/miri/tests/fail/function_calls/return_pointer_aliasing2.stderr39
-rw-r--r--src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.stack.stderr (renamed from src/tools/miri/tests/fail/tree_borrows/retag-data-race.stderr)20
-rw-r--r--src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.tree.stderr26
-rw-r--r--src/tools/miri/tests/fail/tree_borrows/fragile-data-race.rs42
-rw-r--r--src/tools/miri/tests/fail/tree_borrows/fragile-data-race.stderr32
-rw-r--r--src/tools/miri/tests/fail/tree_borrows/reserved/cell-protected-write.rs2
-rw-r--r--src/tools/miri/tests/fail/tree_borrows/reserved/int-protected-write.rs2
-rw-r--r--src/tools/miri/tests/fail/tree_borrows/retag-data-race.rs28
-rw-r--r--src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.rs24
-rw-r--r--src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.stderr20
17 files changed, 253 insertions, 115 deletions
diff --git a/src/tools/miri/tests/fail/both_borrows/retag_data_race_protected_read.rs b/src/tools/miri/tests/fail/both_borrows/retag_data_race_protected_read.rs
new file mode 100644
index 00000000000..f192e76de13
--- /dev/null
+++ b/src/tools/miri/tests/fail/both_borrows/retag_data_race_protected_read.rs
@@ -0,0 +1,29 @@
+//@revisions: stack tree
+//@compile-flags: -Zmiri-preemption-rate=0
+//@[tree]compile-flags: -Zmiri-tree-borrows
+use std::thread;
+
+#[derive(Copy, Clone)]
+struct SendPtr(*mut i32);
+unsafe impl Send for SendPtr {}
+
+fn main() {
+    let mut mem = 0;
+    let ptr = SendPtr(&mut mem as *mut _);
+
+    let t = thread::spawn(move || {
+        let ptr = ptr;
+        // We do a protected 2phase retag (but no write!) in this thread.
+        fn retag(_x: &mut i32) {} //~[tree]ERROR: Data race detected between (1) Read on thread `main` and (2) Write on thread `<unnamed>`
+        retag(unsafe { &mut *ptr.0 }); //~[stack]ERROR: Data race detected between (1) Read on thread `main` and (2) Write on thread `<unnamed>`
+    });
+
+    // We do a read in the main thread.
+    unsafe { ptr.0.read() };
+
+    // These two operations do not commute -- if the read happens after the retag, the retagged pointer
+    // gets frozen! So we want this to be considered UB so that we can still freely move the read around
+    // in this thread without worrying about reordering with retags in other threads.
+
+    t.join().unwrap();
+}
diff --git a/src/tools/miri/tests/fail/both_borrows/retag_data_race_protected_read.stack.stderr b/src/tools/miri/tests/fail/both_borrows/retag_data_race_protected_read.stack.stderr
new file mode 100644
index 00000000000..10fb1dece2a
--- /dev/null
+++ b/src/tools/miri/tests/fail/both_borrows/retag_data_race_protected_read.stack.stderr
@@ -0,0 +1,20 @@
+error: Undefined Behavior: Data race detected between (1) Read on thread `main` and (2) Write on thread `<unnamed>` at ALLOC. (2) just happened here
+  --> $DIR/retag_data_race_protected_read.rs:LL:CC
+   |
+LL |         retag(unsafe { &mut *ptr.0 });
+   |                        ^^^^^^^^^^^ Data race detected between (1) Read on thread `main` and (2) Write on thread `<unnamed>` at ALLOC. (2) just happened here
+   |
+help: and (1) occurred earlier here
+  --> $DIR/retag_data_race_protected_read.rs:LL:CC
+   |
+LL |     unsafe { ptr.0.read() };
+   |              ^^^^^^^^^^^^
+   = 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 (of the first span):
+   = note: inside closure at $DIR/retag_data_race_protected_read.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to previous error
+
diff --git a/src/tools/miri/tests/fail/both_borrows/retag_data_race_protected_read.tree.stderr b/src/tools/miri/tests/fail/both_borrows/retag_data_race_protected_read.tree.stderr
new file mode 100644
index 00000000000..173acf4b96c
--- /dev/null
+++ b/src/tools/miri/tests/fail/both_borrows/retag_data_race_protected_read.tree.stderr
@@ -0,0 +1,25 @@
+error: Undefined Behavior: Data race detected between (1) Read on thread `main` and (2) Write on thread `<unnamed>` at ALLOC. (2) just happened here
+  --> $DIR/retag_data_race_protected_read.rs:LL:CC
+   |
+LL |         fn retag(_x: &mut i32) {}
+   |                  ^^ Data race detected between (1) Read on thread `main` and (2) Write on thread `<unnamed>` at ALLOC. (2) just happened here
+   |
+help: and (1) occurred earlier here
+  --> $DIR/retag_data_race_protected_read.rs:LL:CC
+   |
+LL |     unsafe { ptr.0.read() };
+   |              ^^^^^^^^^^^^
+   = 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 (of the first span):
+   = note: inside `main::{closure#0}::retag` at $DIR/retag_data_race_protected_read.rs:LL:CC
+note: inside closure
+  --> $DIR/retag_data_race_protected_read.rs:LL:CC
+   |
+LL | ...   retag(unsafe { &mut *ptr.0 });
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to previous error
+
diff --git a/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_write.rs b/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.rs
index c1dded40d3c..868b3beb53b 100644
--- a/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_write.rs
+++ b/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.rs
@@ -1,5 +1,7 @@
 //! Make sure that a retag acts like a write for the data race model.
+//@revisions: stack tree
 //@compile-flags: -Zmiri-preemption-rate=0
+//@[tree]compile-flags: -Zmiri-tree-borrows
 #[derive(Copy, Clone)]
 struct SendPtr(*mut u8);
 
@@ -15,7 +17,7 @@ fn thread_1(p: SendPtr) {
 fn thread_2(p: SendPtr) {
     let p = p.0;
     unsafe {
-        *p = 5; //~ ERROR: Data race detected between (1) Write on thread `<unnamed>` and (2) Write on thread `<unnamed>`
+        *p = 5; //~ ERROR: /Data race detected between \(1\) (Read|Write) on thread `<unnamed>` and \(2\) Write on thread `<unnamed>`/
     }
 }
 
diff --git a/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_write.stderr b/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.stack.stderr
index da5af600675..da5af600675 100644
--- a/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_write.stderr
+++ b/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.stack.stderr
diff --git a/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.tree.stderr b/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.tree.stderr
new file mode 100644
index 00000000000..37d216b9877
--- /dev/null
+++ b/src/tools/miri/tests/fail/both_borrows/retag_data_race_write.tree.stderr
@@ -0,0 +1,25 @@
+error: Undefined Behavior: Data race detected between (1) Read on thread `<unnamed>` and (2) Write on thread `<unnamed>` at ALLOC. (2) just happened here
+  --> $DIR/retag_data_race_write.rs:LL:CC
+   |
+LL |         *p = 5;
+   |         ^^^^^^ Data race detected between (1) Read on thread `<unnamed>` and (2) Write on thread `<unnamed>` at ALLOC. (2) just happened here
+   |
+help: and (1) occurred earlier here
+  --> $DIR/retag_data_race_write.rs:LL:CC
+   |
+LL |         let _r = &mut *p;
+   |                  ^^^^^^^
+   = 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 (of the first span):
+   = note: inside `thread_2` at $DIR/retag_data_race_write.rs:LL:CC
+note: inside closure
+  --> $DIR/retag_data_race_write.rs:LL:CC
+   |
+LL |     let t2 = std::thread::spawn(move || thread_2(p));
+   |                                         ^^^^^^^^^^^
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to previous error
+
diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing2.rs b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing2.rs
new file mode 100644
index 00000000000..7e9a6320026
--- /dev/null
+++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing2.rs
@@ -0,0 +1,30 @@
+//@compile-flags: -Zmiri-tree-borrows
+#![feature(raw_ref_op)]
+#![feature(core_intrinsics)]
+#![feature(custom_mir)]
+
+use std::intrinsics::mir::*;
+
+#[custom_mir(dialect = "runtime", phase = "optimized")]
+pub fn main() {
+    mir! {
+        {
+            let x = 0;
+            let ptr = &raw mut x;
+            // We arrange for `myfun` to have a pointer that aliases
+            // its return place. Even just reading from that pointer is UB.
+            Call(x, after_call, myfun(ptr))
+        }
+
+        after_call = {
+            Return()
+        }
+    }
+}
+
+fn myfun(ptr: *mut i32) -> i32 {
+    // This overwrites the return place, which shouldn't be possible through another pointer.
+    unsafe { ptr.write(0) };
+    //~^ ERROR: /write access .* forbidden/
+    13
+}
diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing2.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing2.stderr
new file mode 100644
index 00000000000..33a8a4b46bd
--- /dev/null
+++ b/src/tools/miri/tests/fail/function_calls/return_pointer_aliasing2.stderr
@@ -0,0 +1,39 @@
+error: Undefined Behavior: write access through <TAG> (root of the allocation) is forbidden
+  --> $DIR/return_pointer_aliasing2.rs:LL:CC
+   |
+LL |     unsafe { ptr.write(0) };
+   |              ^^^^^^^^^^^^ write access through <TAG> (root of the allocation) is forbidden
+   |
+   = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
+   = help: the accessed tag <TAG> (root of the allocation) is foreign to the protected tag <TAG> (i.e., it is not a child)
+   = help: this foreign write access would cause the protected tag <TAG> (currently Active) to become Disabled
+   = help: protected tags must never be Disabled
+help: the accessed tag <TAG> was created here
+  --> $DIR/return_pointer_aliasing2.rs:LL:CC
+   |
+LL | /     mir! {
+LL | |         {
+LL | |             let x = 0;
+LL | |             let ptr = &raw mut x;
+...  |
+LL | |         }
+LL | |     }
+   | |_____^
+help: the protected tag <TAG> was created here, in the initial state Active
+  --> $DIR/return_pointer_aliasing2.rs:LL:CC
+   |
+LL |     unsafe { ptr.write(0) };
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   = note: BACKTRACE (of the first span):
+   = note: inside `myfun` at $DIR/return_pointer_aliasing2.rs:LL:CC
+note: inside `main`
+  --> $DIR/return_pointer_aliasing2.rs:LL:CC
+   |
+LL |             Call(x, after_call, myfun(ptr))
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to previous error
+
diff --git a/src/tools/miri/tests/fail/tree_borrows/retag-data-race.stderr b/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.stack.stderr
index f2cdfe7c314..c53a495b5e1 100644
--- a/src/tools/miri/tests/fail/tree_borrows/retag-data-race.stderr
+++ b/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.stack.stderr
@@ -1,23 +1,23 @@
 error: Undefined Behavior: Data race detected between (1) Read on thread `<unnamed>` and (2) Write on thread `<unnamed>` at ALLOC. (2) just happened here
-  --> $DIR/retag-data-race.rs:LL:CC
+  --> $DIR/retag_data_race_read.rs:LL:CC
    |
-LL |     *p = 5;
-   |     ^^^^^^ Data race detected between (1) Read on thread `<unnamed>` and (2) Write on thread `<unnamed>` at ALLOC. (2) just happened here
+LL |         *p = 5;
+   |         ^^^^^^ Data race detected between (1) Read on thread `<unnamed>` and (2) Write on thread `<unnamed>` at ALLOC. (2) just happened here
    |
 help: and (1) occurred earlier here
-  --> $DIR/retag-data-race.rs:LL:CC
+  --> $DIR/retag_data_race_read.rs:LL:CC
    |
-LL |     let _r = &*p;
-   |              ^^^
+LL |         let _r = &*p;
+   |                  ^^^
    = 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 (of the first span):
-   = note: inside `thread_2` at $DIR/retag-data-race.rs:LL:CC
+   = note: inside `thread_2` at $DIR/retag_data_race_read.rs:LL:CC
 note: inside closure
-  --> $DIR/retag-data-race.rs:LL:CC
+  --> $DIR/retag_data_race_read.rs:LL:CC
    |
-LL |     let t2 = std::thread::spawn(move || unsafe { thread_2(p) });
-   |                                                  ^^^^^^^^^^^
+LL |     let t2 = std::thread::spawn(move || thread_2(p));
+   |                                         ^^^^^^^^^^^
 
 note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
 
diff --git a/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.tree.stderr b/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.tree.stderr
new file mode 100644
index 00000000000..1e154eb0564
--- /dev/null
+++ b/src/tools/miri/tests/fail/stacked_borrows/retag_data_race_read.tree.stderr
@@ -0,0 +1,26 @@
+error: Undefined Behavior: reborrow through <TAG> (root of the allocation) is forbidden
+  --> RUSTLIB/std/src/rt.rs:LL:CC
+   |
+LL |     panic::catch_unwind(move || unsafe { init(argc, argv, sigpipe) }).map_err(rt_abort)?;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reborrow through <TAG> (root of the allocation) is forbidden
+   |
+   = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
+   = help: the accessed tag <TAG> (root of the allocation) is foreign to the protected tag <TAG> (i.e., it is not a child)
+   = help: this reborrow (acting as a foreign read access) would cause the protected tag <TAG> (currently Active) to become Disabled
+   = help: protected tags must never be Disabled
+help: the accessed tag <TAG> was created here
+  --> RUSTLIB/std/src/rt.rs:LL:CC
+   |
+LL |     panic::catch_unwind(move || unsafe { init(argc, argv, sigpipe) }).map_err(rt_abort)?;
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: the protected tag <TAG> was created here, in the initial state Active
+  --> RUSTLIB/std/src/panic.rs:LL:CC
+   |
+LL | pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
+   |                                                       ^
+   = note: BACKTRACE (of the first span):
+   = note: inside `std::rt::lang_start_internal` at RUSTLIB/std/src/rt.rs:LL:CC
+   = note: inside `std::rt::lang_start::<()>` at RUSTLIB/std/src/rt.rs:LL:CC
+
+error: aborting due to previous error
+
diff --git a/src/tools/miri/tests/fail/tree_borrows/fragile-data-race.rs b/src/tools/miri/tests/fail/tree_borrows/fragile-data-race.rs
deleted file mode 100644
index 215100de0a1..00000000000
--- a/src/tools/miri/tests/fail/tree_borrows/fragile-data-race.rs
+++ /dev/null
@@ -1,42 +0,0 @@
-//! Race-condition-like interaction between a read and a reborrow.
-//! Even though no write or fake write occurs, reads have an effect on protected
-//! Reserved. This is a protected-retag/read data race, but is not *detected* as
-//! a data race violation because reborrows are not writes.
-//!
-//! This test is sensitive to the exact schedule so we disable preemption.
-//@compile-flags: -Zmiri-tree-borrows -Zmiri-preemption-rate=0
-use std::ptr::addr_of_mut;
-use std::thread;
-
-#[derive(Copy, Clone)]
-struct SendPtr(*mut u8);
-
-unsafe impl Send for SendPtr {}
-
-// First thread is just a reborrow, but for an instant `x` is
-// protected and thus vulnerable to foreign reads.
-fn thread_1(x: &mut u8) -> SendPtr {
-    thread::yield_now(); // make the other thread go first
-    SendPtr(x as *mut u8)
-}
-
-// Second thread simply performs a read.
-fn thread_2(x: &u8) {
-    let _val = *x;
-}
-
-fn main() {
-    let mut x = 0u8;
-    let x_1 = unsafe { &mut *addr_of_mut!(x) };
-    let xg = unsafe { &*addr_of_mut!(x) };
-
-    // The two threads are executed in parallel on aliasing pointers.
-    // UB occurs if the read of thread_2 occurs while the protector of thread_1
-    // is in place.
-    let hf = thread::spawn(move || thread_1(x_1));
-    let hg = thread::spawn(move || thread_2(xg));
-    let SendPtr(p) = hf.join().unwrap();
-    let () = hg.join().unwrap();
-
-    unsafe { *p = 1 }; //~ ERROR: /write access through .* is forbidden/
-}
diff --git a/src/tools/miri/tests/fail/tree_borrows/fragile-data-race.stderr b/src/tools/miri/tests/fail/tree_borrows/fragile-data-race.stderr
deleted file mode 100644
index 910f51ba8a3..00000000000
--- a/src/tools/miri/tests/fail/tree_borrows/fragile-data-race.stderr
+++ /dev/null
@@ -1,32 +0,0 @@
-error: Undefined Behavior: write access through <TAG> is forbidden
-  --> $DIR/fragile-data-race.rs:LL:CC
-   |
-LL |     unsafe { *p = 1 };
-   |              ^^^^^^ write access through <TAG> is forbidden
-   |
-   = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
-   = help: the accessed tag <TAG> is a child of the conflicting tag <TAG>
-   = help: the conflicting tag <TAG> has state Frozen which forbids this child write access
-help: the accessed tag <TAG> was created here
-  --> $DIR/fragile-data-race.rs:LL:CC
-   |
-LL | fn thread_1(x: &mut u8) -> SendPtr {
-   |             ^
-help: the conflicting tag <TAG> was created here, in the initial state Reserved
-  --> RUSTLIB/std/src/panic.rs:LL:CC
-   |
-LL | pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
-   |                                                       ^
-help: the conflicting tag <TAG> later transitioned to Frozen due to a reborrow (acting as a foreign read access) at offsets [0x0..0x1]
-  --> RUSTLIB/core/src/ptr/mod.rs:LL:CC
-   |
-LL |         crate::intrinsics::read_via_copy(src)
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: this transition corresponds to a loss of write permissions
-   = note: BACKTRACE (of the first span):
-   = note: inside `main` at $DIR/fragile-data-race.rs:LL:CC
-
-note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
-
-error: aborting due to previous error
-
diff --git a/src/tools/miri/tests/fail/tree_borrows/reserved/cell-protected-write.rs b/src/tools/miri/tests/fail/tree_borrows/reserved/cell-protected-write.rs
index 872efe3ad59..465679b72c3 100644
--- a/src/tools/miri/tests/fail/tree_borrows/reserved/cell-protected-write.rs
+++ b/src/tools/miri/tests/fail/tree_borrows/reserved/cell-protected-write.rs
@@ -3,8 +3,8 @@
 // Check how a Reserved with interior mutability
 // responds to a Foreign Write under a Protector
 #[path = "../../../utils/mod.rs"]
+#[macro_use]
 mod utils;
-use utils::macros::*;
 
 use std::cell::UnsafeCell;
 
diff --git a/src/tools/miri/tests/fail/tree_borrows/reserved/int-protected-write.rs b/src/tools/miri/tests/fail/tree_borrows/reserved/int-protected-write.rs
index 3a1205a84f7..1e6e2eebd26 100644
--- a/src/tools/miri/tests/fail/tree_borrows/reserved/int-protected-write.rs
+++ b/src/tools/miri/tests/fail/tree_borrows/reserved/int-protected-write.rs
@@ -1,8 +1,8 @@
 //@compile-flags: -Zmiri-tree-borrows -Zmiri-tag-gc=0
 
 #[path = "../../../utils/mod.rs"]
+#[macro_use]
 mod utils;
-use utils::macros::*;
 
 // Check how a Reserved without interior mutability responds to a Foreign
 // Write when under a protector
diff --git a/src/tools/miri/tests/fail/tree_borrows/retag-data-race.rs b/src/tools/miri/tests/fail/tree_borrows/retag-data-race.rs
deleted file mode 100644
index 8ef3d23e804..00000000000
--- a/src/tools/miri/tests/fail/tree_borrows/retag-data-race.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-//! Make sure that a retag acts like a read for the data race model.
-//! This is a retag/write race condition.
-//!
-//! This test is sensitive to the exact schedule so we disable preemption.
-//@compile-flags: -Zmiri-tree-borrows -Zmiri-preemption-rate=0
-#[derive(Copy, Clone)]
-struct SendPtr(*mut u8);
-
-unsafe impl Send for SendPtr {}
-
-unsafe fn thread_1(SendPtr(p): SendPtr) {
-    let _r = &*p;
-}
-
-unsafe fn thread_2(SendPtr(p): SendPtr) {
-    *p = 5; //~ ERROR: Data race detected between (1) Read on thread `<unnamed>` and (2) Write on thread `<unnamed>`
-}
-
-fn main() {
-    let mut x = 0;
-    let p = std::ptr::addr_of_mut!(x);
-    let p = SendPtr(p);
-
-    let t1 = std::thread::spawn(move || unsafe { thread_1(p) });
-    let t2 = std::thread::spawn(move || unsafe { thread_2(p) });
-    let _ = t1.join();
-    let _ = t2.join();
-}
diff --git a/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.rs b/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.rs
new file mode 100644
index 00000000000..fa1812adc29
--- /dev/null
+++ b/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.rs
@@ -0,0 +1,24 @@
+/// This tests that when a field sits at offset 0 in a 4-aligned struct, accessing the field
+/// requires alignment 4 even if the field type has lower alignment requirements.
+
+#[repr(C)]
+pub struct S {
+    x: u8,
+    y: u32,
+}
+
+unsafe fn foo(x: *const S) -> u8 {
+    unsafe { (*x).x } //~ERROR: accessing memory with alignment 1, but alignment 4 is required
+}
+
+fn main() {
+    unsafe {
+        let mem = [0u64; 16];
+        let odd_ptr = std::ptr::addr_of!(mem).cast::<u8>().add(1);
+        // `odd_ptr` is now not aligned enough for `S`.
+        // If accessing field `x` can exploit that it is at offset 0
+        // in a 4-aligned struct, that field access requires alignment 4,
+        // thus making this UB.
+        foo(odd_ptr.cast());
+    }
+}
diff --git a/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.stderr b/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.stderr
new file mode 100644
index 00000000000..0f030a6e27c
--- /dev/null
+++ b/src/tools/miri/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.stderr
@@ -0,0 +1,20 @@
+error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required
+  --> $DIR/field_requires_parent_struct_alignment.rs:LL:CC
+   |
+LL |     unsafe { (*x).x }
+   |              ^^^^^^ accessing memory with alignment ALIGN, but alignment ALIGN is required
+   |
+   = 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 `foo` at $DIR/field_requires_parent_struct_alignment.rs:LL:CC
+note: inside `main`
+  --> $DIR/field_requires_parent_struct_alignment.rs:LL:CC
+   |
+LL |         foo(odd_ptr.cast());
+   |         ^^^^^^^^^^^^^^^^^^^
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to previous error
+