about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorDylan MacKenzie <ecstaticmorse@gmail.com>2019-10-01 20:14:27 -0700
committerDylan MacKenzie <ecstaticmorse@gmail.com>2019-10-01 22:16:15 -0700
commit33aa5e855ed1deec5d086c7919b2a9572128b7ee (patch)
treecaebae87c68a86b75c9164aa202cd7897d582809 /src/test
parent767550ef0fc0a01abd8dc50fead0967d215eca41 (diff)
downloadrust-33aa5e855ed1deec5d086c7919b2a9572128b7ee.tar.gz
rust-33aa5e855ed1deec5d086c7919b2a9572128b7ee.zip
Add test exposing unsoundness in `IndirectlyMutableLocals`
Diffstat (limited to 'src/test')
-rw-r--r--src/test/ui/mir-dataflow/indirect-mutation-offset.rs42
-rw-r--r--src/test/ui/mir-dataflow/indirect-mutation-offset.stderr10
2 files changed, 52 insertions, 0 deletions
diff --git a/src/test/ui/mir-dataflow/indirect-mutation-offset.rs b/src/test/ui/mir-dataflow/indirect-mutation-offset.rs
new file mode 100644
index 00000000000..804b70d2652
--- /dev/null
+++ b/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);
+}
diff --git a/src/test/ui/mir-dataflow/indirect-mutation-offset.stderr b/src/test/ui/mir-dataflow/indirect-mutation-offset.stderr
new file mode 100644
index 00000000000..16bd1781313
--- /dev/null
+++ b/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
+