fix miri_promise_symbolic_alignment for huge alignments
This commit is contained in:
parent
6237f2381d
commit
ff95f8b872
4 changed files with 46 additions and 3 deletions
|
|
@ -558,14 +558,23 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
|
|||
|
||||
// Promises that a pointer has a given symbolic alignment.
|
||||
"miri_promise_symbolic_alignment" => {
|
||||
use rustc_target::abi::AlignFromBytesError;
|
||||
|
||||
let [ptr, align] = this.check_shim(abi, Abi::Rust, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let align = this.read_target_usize(align)?;
|
||||
let Ok(align) = Align::from_bytes(align) else {
|
||||
if !align.is_power_of_two() {
|
||||
throw_unsup_format!(
|
||||
"`miri_promise_symbolic_alignment`: alignment must be a power of 2"
|
||||
"`miri_promise_symbolic_alignment`: alignment must be a power of 2, got {align}"
|
||||
);
|
||||
};
|
||||
}
|
||||
let align = Align::from_bytes(align).unwrap_or_else(|err| {
|
||||
match err {
|
||||
AlignFromBytesError::NotPowerOfTwo(_) => unreachable!(),
|
||||
// When the alignment is a power of 2 but too big, clamp it to MAX.
|
||||
AlignFromBytesError::TooLarge(_) => Align::MAX,
|
||||
}
|
||||
});
|
||||
let (_, addr) = ptr.into_parts(); // we know the offset is absolute
|
||||
// Cannot panic since `align` is a power of 2 and hence non-zero.
|
||||
if addr.bytes().checked_rem(align.bytes()).unwrap() != 0 {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
#[path = "../../utils/mod.rs"]
|
||||
mod utils;
|
||||
|
||||
fn main() {
|
||||
let buffer = [0u32; 128];
|
||||
unsafe { utils::miri_promise_symbolic_alignment(buffer.as_ptr().cast(), 0) };
|
||||
//~^ERROR: alignment must be a power of 2
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
error: unsupported operation: `miri_promise_symbolic_alignment`: alignment must be a power of 2, got 0
|
||||
--> $DIR/promise_alignment_zero.rs:LL:CC
|
||||
|
|
||||
LL | unsafe { utils::miri_promise_symbolic_alignment(buffer.as_ptr().cast(), 0) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `miri_promise_symbolic_alignment`: alignment must be a power of 2, got 0
|
||||
|
|
||||
= 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_zero.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
|
||||
|
||||
|
|
@ -90,9 +90,21 @@ fn test_cstr() {
|
|||
std::ffi::CStr::from_bytes_with_nul(b"this is a test that is longer than 16 bytes\0").unwrap();
|
||||
}
|
||||
|
||||
fn huge_align() {
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
const SIZE: usize = 1 << 47;
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
const SIZE: usize = 1 << 30;
|
||||
#[cfg(target_pointer_width = "16")]
|
||||
const SIZE: usize = 1 << 13;
|
||||
struct HugeSize([u8; SIZE - 1]);
|
||||
let _ = std::ptr::invalid::<HugeSize>(SIZE).align_offset(SIZE);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
test_align_to();
|
||||
test_from_utf8();
|
||||
test_u64_array();
|
||||
test_cstr();
|
||||
huge_align();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue