about summary refs log tree commit diff
path: root/src/tools/miri/tests/fail
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2023-11-12 16:06:50 +0100
committerRalf Jung <post@ralfj.de>2023-12-03 21:51:14 +0100
commitbebba4f6e05fae60ce8dcddc5eb6b4e7686bd995 (patch)
treeabfa4f9082f8369161b2cfa7a6dce5d8f32e4781 /src/tools/miri/tests/fail
parent7ceaf198684b7ca94986a436bf623e20ba62bd23 (diff)
downloadrust-bebba4f6e05fae60ce8dcddc5eb6b4e7686bd995.tar.gz
rust-bebba4f6e05fae60ce8dcddc5eb6b4e7686bd995.zip
miri: support 'promising' alignment for symbolic alignment check
Diffstat (limited to 'src/tools/miri/tests/fail')
-rw-r--r--src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.call_unaligned_ptr.stderr14
-rw-r--r--src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.read_unaligned_ptr.stderr15
-rw-r--r--src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.rs54
3 files changed, 83 insertions, 0 deletions
diff --git a/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.call_unaligned_ptr.stderr b/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.call_unaligned_ptr.stderr
new file mode 100644
index 00000000000..e23ac5ac2fc
--- /dev/null
+++ b/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.call_unaligned_ptr.stderr
@@ -0,0 +1,14 @@
+error: unsupported operation: `miri_promise_symbolic_alignment`: pointer is not actually aligned
+  --> $DIR/promise_alignment.rs:LL:CC
+   |
+LL |         unsafe { utils::miri_promise_symbolic_alignment(align8.add(1).cast(), 8) };
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `miri_promise_symbolic_alignment`: pointer is not actually aligned
+   |
+   = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support
+   = note: BACKTRACE:
+   = note: inside `main` at $DIR/promise_alignment.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.read_unaligned_ptr.stderr b/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.read_unaligned_ptr.stderr
new file mode 100644
index 00000000000..0842ccd6d5b
--- /dev/null
+++ b/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.read_unaligned_ptr.stderr
@@ -0,0 +1,15 @@
+error: Undefined Behavior: accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required
+  --> $DIR/promise_alignment.rs:LL:CC
+   |
+LL |         let _val = unsafe { align8.cast::<Align16>().read() };
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required
+   |
+   = help: this usually indicates that your program performed an invalid operation and caused Undefined Behavior
+   = help: but due to `-Zmiri-symbolic-alignment-check`, alignment errors can also be false positives
+   = note: BACKTRACE:
+   = note: inside `main` at $DIR/promise_alignment.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.rs b/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.rs
new file mode 100644
index 00000000000..d2d49c604af
--- /dev/null
+++ b/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.rs
@@ -0,0 +1,54 @@
+//@compile-flags: -Zmiri-symbolic-alignment-check
+//@revisions: call_unaligned_ptr read_unaligned_ptr
+#![feature(strict_provenance)]
+
+#[path = "../../utils/mod.rs"]
+mod utils;
+
+#[repr(align(8))]
+#[derive(Copy, Clone)]
+struct Align8(u64);
+
+fn main() {
+    let buffer = [0u32; 128]; // get some 4-aligned memory
+    let buffer = buffer.as_ptr();
+    // "Promising" the alignment down to 1 must not hurt.
+    unsafe { utils::miri_promise_symbolic_alignment(buffer.cast(), 1) };
+    let _val = unsafe { buffer.read() };
+
+    // Let's find a place to promise alignment 8.
+    let align8 = if buffer.addr() % 8 == 0 {
+        buffer
+    } else {
+        buffer.wrapping_add(1)
+    };
+    assert!(align8.addr() % 8 == 0);
+    unsafe { utils::miri_promise_symbolic_alignment(align8.cast(), 8) };
+    // Promising the alignment down to 1 *again* still must not hurt.
+    unsafe { utils::miri_promise_symbolic_alignment(buffer.cast(), 1) };
+    // Now we can do 8-aligned reads here.
+    let _val = unsafe { align8.cast::<Align8>().read() };
+
+    // Make sure we error if the pointer is not actually aligned.
+    if cfg!(call_unaligned_ptr) {
+        unsafe { utils::miri_promise_symbolic_alignment(align8.add(1).cast(), 8) };
+        //~[call_unaligned_ptr]^ ERROR: pointer is not actually aligned
+    }
+
+    // Also don't accept even higher-aligned reads.
+    if cfg!(read_unaligned_ptr) {
+        #[repr(align(16))]
+        #[derive(Copy, Clone)]
+        struct Align16(u128);
+
+        let align16 = if align8.addr() % 16 == 0 {
+            align8
+        } else {
+            align8.wrapping_add(2)
+        };
+        assert!(align16.addr() % 16 == 0);
+
+        let _val = unsafe { align8.cast::<Align16>().read() };
+        //~[read_unaligned_ptr]^ ERROR: accessing memory based on pointer with alignment 8, but alignment 16 is required
+    }
+}