blob: e075db66039bc59f358505cc62ea751cb1737461 [file] [log] [blame]
//@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(#[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
}
}