about summary refs log tree commit diff
path: root/src/tools/miri/tests/fail/unaligned_pointers/promise_alignment.rs
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
    }
}