Skip to content

Commit 33aa5e8

Browse files
Add test exposing unsoundness in IndirectlyMutableLocals
1 parent 767550e commit 33aa5e8

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// compile-flags: -Zunleash-the-miri-inside-of-you
2+
3+
#![feature(core_intrinsics, rustc_attrs, const_raw_ptr_deref)]
4+
5+
use std::cell::UnsafeCell;
6+
use std::intrinsics::rustc_peek;
7+
8+
#[repr(C)]
9+
struct PartialInteriorMut {
10+
zst: [i32; 0],
11+
cell: UnsafeCell<i32>,
12+
}
13+
14+
#[rustc_mir(rustc_peek_indirectly_mutable,stop_after_dataflow)]
15+
#[rustc_mir(borrowck_graphviz_postflow="indirect.dot")]
16+
const BOO: i32 = {
17+
let x = PartialInteriorMut {
18+
zst: [],
19+
cell: UnsafeCell::new(0),
20+
};
21+
22+
let p_zst: *const _ = &x.zst ; // Doesn't cause `x` to get marked as indirectly mutable.
23+
24+
let rmut_cell = unsafe {
25+
// Take advantage of the fact that `zst` and `cell` are at the same location in memory.
26+
// This trick would work with any size type if miri implemented `ptr::offset`.
27+
let p_cell = p_zst as *const UnsafeCell<i32>;
28+
29+
let pmut_cell = (*p_cell).get();
30+
&mut *pmut_cell
31+
};
32+
33+
*rmut_cell = 42; // Mutates `x` indirectly even though `x` is not marked indirectly mutable!!!
34+
let val = *rmut_cell;
35+
unsafe { rustc_peek(x) }; //~ ERROR rustc_peek: bit not set
36+
37+
val
38+
};
39+
40+
fn main() {
41+
println!("{}", BOO);
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: rustc_peek: bit not set
2+
--> $DIR/indirect-mutation-offset.rs:35:14
3+
|
4+
LL | unsafe { rustc_peek(x) };
5+
| ^^^^^^^^^^^^^
6+
7+
error: stop_after_dataflow ended compilation
8+
9+
error: aborting due to 2 previous errors
10+

0 commit comments

Comments
 (0)