blob: 009ce1eb882620488e8f47c2449859ef3c6b2b22 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
//@compile-flags: -Zmiri-symbolic-alignment-check
//@revisions: call_unaligned_ptr read_unaligned_ptr
#[path = "../../utils/mod.rs"]
mod utils;
#[repr(align(8))]
#[derive(Copy, Clone)]
struct Align8(#[allow(dead_code)] 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(#[allow(dead_code)] 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
}
}
|