Skip to content

Commit 90c9e32

Browse files
committed
consolidate miri-unleashed tests for mutable refs into one file
1 parent c1e3f03 commit 90c9e32

File tree

4 files changed

+399
-427
lines changed

4 files changed

+399
-427
lines changed

Diff for: tests/ui/consts/miri_unleashed/mutable_references.rs

+87-3
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,20 @@
22
//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)"
33
//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP"
44

5+
#![allow(static_mut_refs)]
56
#![deny(const_eval_mutable_ptr_in_final_value)]
67
use std::cell::UnsafeCell;
8+
use std::sync::atomic::*;
9+
10+
// # Plain `&mut` in the final value
711

812
// This requires walking nested statics.
913
static FOO: &&mut u32 = &&mut 42;
1014
//~^ ERROR it is undefined behavior to use this value
11-
15+
//~| pointing to read-only memory
16+
static OH_YES: &mut i32 = &mut 42;
17+
//~^ ERROR it is undefined behavior to use this value
18+
//~| pointing to read-only memory
1219
static BAR: &mut () = &mut ();
1320
//~^ ERROR encountered mutable pointer in final value of static
1421
//~| WARNING this was previously accepted by the compiler
@@ -19,15 +26,92 @@ static BOO: &mut Foo<()> = &mut Foo(());
1926
//~^ ERROR encountered mutable pointer in final value of static
2027
//~| WARNING this was previously accepted by the compiler
2128

29+
const BLUNT: &mut i32 = &mut 42;
30+
//~^ ERROR: it is undefined behavior to use this value
31+
//~| pointing to read-only memory
32+
33+
const SUBTLE: &mut i32 = unsafe { static mut STATIC: i32 = 0; &mut STATIC };
34+
//~^ ERROR: it is undefined behavior to use this value
35+
//~| static
36+
37+
// # Interior mutability
38+
2239
struct Meh {
2340
x: &'static UnsafeCell<i32>,
2441
}
2542
unsafe impl Sync for Meh {}
2643
static MEH: Meh = Meh { x: &UnsafeCell::new(42) };
2744
//~^ ERROR it is undefined behavior to use this value
45+
//~| `UnsafeCell` in read-only memory
46+
// Same with a const:
47+
// the following will never be ok! no interior mut behind consts, because
48+
// all allocs interned here will be marked immutable.
49+
const MUH: Meh = Meh {
50+
//~^ ERROR it is undefined behavior to use this value
51+
//~| `UnsafeCell` in read-only memory
52+
x: &UnsafeCell::new(42),
53+
};
54+
55+
struct Synced {
56+
x: UnsafeCell<i32>,
57+
}
58+
unsafe impl Sync for Synced {}
59+
60+
// Make sure we also catch this behind a type-erased `dyn Trait` reference.
61+
const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) };
62+
//~^ ERROR: it is undefined behavior to use this value
63+
//~| `UnsafeCell` in read-only memory
64+
65+
// # Check for mutable references to read-only memory
66+
67+
static READONLY: i32 = 0;
68+
static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
69+
//~^ ERROR: it is undefined behavior to use this value
70+
//~| pointing to read-only memory
71+
72+
// # Check for consts pointing to mutable memory
73+
74+
static mut MUTABLE: i32 = 42;
75+
const POINTS_TO_MUTABLE: &i32 = unsafe { &MUTABLE }; //~ERROR: undefined behavior
76+
//~| encountered reference to mutable memory
77+
static mut MUTABLE_REF: &mut i32 = &mut 42;
78+
const POINTS_TO_MUTABLE2: &i32 = unsafe { &*MUTABLE_REF };
79+
//~^ ERROR: evaluation of constant value failed
80+
//~| accesses mutable global memory
81+
82+
const POINTS_TO_MUTABLE_INNER: *const i32 = &mut 42 as *mut _ as *const _;
83+
//~^ ERROR: mutable pointer in final value
84+
//~| WARNING this was previously accepted by the compiler
85+
86+
const POINTS_TO_MUTABLE_INNER2: *const i32 = &mut 42 as *const _;
87+
//~^ ERROR: mutable pointer in final value
88+
//~| WARNING this was previously accepted by the compiler
89+
90+
const INTERIOR_MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _;
91+
//~^ ERROR: mutable pointer in final value
92+
//~| WARNING this was previously accepted by the compiler
93+
94+
struct SyncPtr<T> {
95+
x: *const T,
96+
}
97+
unsafe impl<T> Sync for SyncPtr<T> {}
98+
99+
// These pass the lifetime checks because of the "tail expression" / "outer scope" rule.
100+
// (This relies on `SyncPtr` being a curly brace struct.)
101+
// However, we intern the inner memory as read-only, so this must be rejected.
102+
// (Also see `static-no-inner-mut` for similar tests on `static`.)
103+
const RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };
104+
//~^ ERROR mutable pointer in final value
105+
//~| WARNING this was previously accepted by the compiler
106+
107+
const RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x: &mut 42 as *mut _ as *const _ };
108+
//~^ ERROR mutable pointer in final value
109+
//~| WARNING this was previously accepted by the compiler
110+
111+
const RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
112+
//~^ ERROR mutable pointer in final value
113+
//~| WARNING this was previously accepted by the compiler
28114

29-
static OH_YES: &mut i32 = &mut 42;
30-
//~^ ERROR it is undefined behavior to use this value
31115

32116
fn main() {
33117
unsafe {

0 commit comments

Comments
 (0)