]> git.lizzy.rs Git - rust.git/blob - src/tools/miri/tests/fail/weak_memory/racing_mixed_size.rs
Rollup merge of #101664 - mejrs:similarity, r=fee1-dead
[rust.git] / src / tools / miri / tests / fail / weak_memory / racing_mixed_size.rs
1 // We want to control preemption here.
2 //@compile-flags: -Zmiri-preemption-rate=0
3
4 #![feature(core_intrinsics)]
5
6 use std::ptr;
7 use std::sync::atomic::AtomicU32;
8 use std::sync::atomic::Ordering::*;
9 use std::thread::spawn;
10
11 fn static_atomic_u32(val: u32) -> &'static AtomicU32 {
12     let ret = Box::leak(Box::new(AtomicU32::new(val)));
13     ret
14 }
15
16 fn split_u32_ptr(dword: *const u32) -> *const [u16; 2] {
17     unsafe { std::mem::transmute::<*const u32, *const [u16; 2]>(dword) }
18 }
19
20 // Wine's SRWLock implementation does this, which is definitely undefined in C++ memory model
21 // https://github.com/wine-mirror/wine/blob/303f8042f9db508adaca02ef21f8de4992cb9c03/dlls/ntdll/sync.c#L543-L566
22 // Though it probably works just fine on x86
23 pub fn main() {
24     let x = static_atomic_u32(0);
25     let j1 = spawn(move || {
26         x.store(1, Relaxed);
27     });
28
29     let j2 = spawn(move || {
30         let x_ptr = x as *const AtomicU32 as *const u32;
31         let x_split = split_u32_ptr(x_ptr);
32         unsafe {
33             let hi = ptr::addr_of!((*x_split)[0]);
34             std::intrinsics::atomic_load_relaxed(hi); //~ ERROR: imperfectly overlapping
35         }
36     });
37
38     j1.join().unwrap();
39     j2.join().unwrap();
40 }