throw_unsup_format for alignment greater than 2^29 and refactor non-power-of-two alignment check

This commit is contained in:
tiif 2024-08-09 12:16:47 +08:00
parent dc9f4e8c4c
commit 6552a82166
5 changed files with 68 additions and 3 deletions

View file

@ -8,7 +8,7 @@ use rustc_middle::mir;
use rustc_middle::ty;
use rustc_span::Symbol;
use rustc_target::{
abi::{Align, Size},
abi::{Align, AlignFromBytesError, Size},
spec::abi::Abi,
};
@ -199,9 +199,20 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
if i128::from(size) > this.tcx.data_layout.pointer_size.signed_int_max() {
throw_ub_format!("creating an allocation larger than half the address space");
}
if !align.is_power_of_two() {
throw_ub_format!("creating allocation with non-power-of-two alignment {}", align);
if let Err(e) = Align::from_bytes(align) {
match e {
AlignFromBytesError::TooLarge(_) => {
throw_unsup_format!(
"creating allocation with alignment {align} exceeding rustc's maximum \
supported value"
);
}
AlignFromBytesError::NotPowerOfTwo(_) => {
throw_ub_format!("creating allocation with non-power-of-two alignment {align}");
}
}
}
Ok(())
}

View file

@ -0,0 +1,14 @@
// Previously, attempting to allocate with an alignment greater than 2^29 would cause miri to ICE
// because rustc does not support alignments that large.
// https://github.com/rust-lang/miri/issues/3687
extern "Rust" {
fn __rust_alloc(size: usize, align: usize) -> *mut u8;
}
fn main() {
unsafe {
__rust_alloc(1, 1 << 30);
//~^ERROR: exceeding rustc's maximum supported value
}
}

View file

@ -0,0 +1,14 @@
error: unsupported operation: creating allocation with alignment ALIGN exceeding rustc's maximum supported value
--> $DIR/unsupported_big_alignment.rs:LL:CC
|
LL | __rust_alloc(1, 1 << 30);
| ^^^^^^^^^^^^^^^^^^^^^^^^ creating allocation with alignment ALIGN exceeding rustc's maximum supported value
|
= help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support
= note: BACKTRACE:
= note: inside `main` at $DIR/unsupported_big_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

View file

@ -0,0 +1,11 @@
// Test non-power-of-two alignment.
extern "Rust" {
fn __rust_alloc(size: usize, align: usize) -> *mut u8;
}
fn main() {
unsafe {
__rust_alloc(1, 3);
//~^ERROR: creating allocation with non-power-of-two alignment
}
}

View file

@ -0,0 +1,15 @@
error: Undefined Behavior: creating allocation with non-power-of-two alignment ALIGN
--> $DIR/unsupported_non_power_two_alignment.rs:LL:CC
|
LL | __rust_alloc(1, 3);
| ^^^^^^^^^^^^^^^^^^ creating allocation with non-power-of-two alignment ALIGN
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: BACKTRACE:
= note: inside `main` at $DIR/unsupported_non_power_two_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