Skip to content

Commit

Permalink
Add test exposing unsoundness in IndirectlyMutableLocals
Browse files Browse the repository at this point in the history
  • Loading branch information
ecstatic-morse committed Oct 2, 2019
1 parent 767550e commit 33aa5e8
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 0 deletions.
42 changes: 42 additions & 0 deletions src/test/ui/mir-dataflow/indirect-mutation-offset.rs
@@ -0,0 +1,42 @@
// compile-flags: -Zunleash-the-miri-inside-of-you

#![feature(core_intrinsics, rustc_attrs, const_raw_ptr_deref)]

use std::cell::UnsafeCell;
use std::intrinsics::rustc_peek;

#[repr(C)]
struct PartialInteriorMut {
zst: [i32; 0],
cell: UnsafeCell<i32>,
}

#[rustc_mir(rustc_peek_indirectly_mutable,stop_after_dataflow)]
#[rustc_mir(borrowck_graphviz_postflow="indirect.dot")]
const BOO: i32 = {
let x = PartialInteriorMut {
zst: [],
cell: UnsafeCell::new(0),
};

let p_zst: *const _ = &x.zst ; // Doesn't cause `x` to get marked as indirectly mutable.

let rmut_cell = unsafe {
// Take advantage of the fact that `zst` and `cell` are at the same location in memory.
// This trick would work with any size type if miri implemented `ptr::offset`.
let p_cell = p_zst as *const UnsafeCell<i32>;

let pmut_cell = (*p_cell).get();
&mut *pmut_cell
};

*rmut_cell = 42; // Mutates `x` indirectly even though `x` is not marked indirectly mutable!!!
let val = *rmut_cell;
unsafe { rustc_peek(x) }; //~ ERROR rustc_peek: bit not set

val
};

fn main() {
println!("{}", BOO);
}
10 changes: 10 additions & 0 deletions src/test/ui/mir-dataflow/indirect-mutation-offset.stderr
@@ -0,0 +1,10 @@
error: rustc_peek: bit not set
--> $DIR/indirect-mutation-offset.rs:35:14
|
LL | unsafe { rustc_peek(x) };
| ^^^^^^^^^^^^^

error: stop_after_dataflow ended compilation

error: aborting due to 2 previous errors

0 comments on commit 33aa5e8

Please sign in to comment.