Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 73db2e4

Browse files
committed
Auto merge of rust-lang#3211 - RalfJung:promise, r=RalfJung
fix promising a very large alignment Also make use of rust-lang#118565 to simplify some SIMD intrinsics, while we are at it
2 parents 88d905c + 1fa8fd8 commit 73db2e4

File tree

6 files changed

+48
-16
lines changed

6 files changed

+48
-16
lines changed

‎src/tools/miri/src/shims/foreign_items.rs‎

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -558,14 +558,23 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
558558

559559
// Promises that a pointer has a given symbolic alignment.
560560
"miri_promise_symbolic_alignment" => {
561+
use rustc_target::abi::AlignFromBytesError;
562+
561563
let [ptr, align] = this.check_shim(abi, Abi::Rust, link_name, args)?;
562564
let ptr = this.read_pointer(ptr)?;
563565
let align = this.read_target_usize(align)?;
564-
letOk(align) = Align::from_bytes(align)else {
566+
if !align.is_power_of_two() {
565567
throw_unsup_format!(
566-
"`miri_promise_symbolic_alignment`: alignment must be a power of 2"
568+
"`miri_promise_symbolic_alignment`: alignment must be a power of 2, got {align}"
567569
);
568-
};
570+
}
571+
let align = Align::from_bytes(align).unwrap_or_else(|err| {
572+
match err {
573+
AlignFromBytesError::NotPowerOfTwo(_) => unreachable!(),
574+
// When the alignment is a power of 2 but too big, clamp it to MAX.
575+
AlignFromBytesError::TooLarge(_) => Align::MAX,
576+
}
577+
});
569578
let (_, addr) = ptr.into_parts(); // we know the offset is absolute
570579
// Cannot panic since `align` is a power of 2 and hence non-zero.
571580
if addr.bytes().checked_rem(align.bytes()).unwrap() != 0 {

‎src/tools/miri/src/shims/intrinsics/simd.rs‎

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -115,18 +115,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
115115
}
116116
}
117117
Op::Numeric(name) => {
118-
assert!(op.layout.ty.is_integral());
119-
let size = op.layout.size;
120-
let bits = op.to_scalar().to_bits(size).unwrap();
121-
let extra = 128u128.checked_sub(u128::from(size.bits())).unwrap();
122-
let bits_out = match name {
123-
sym::ctlz => u128::from(bits.leading_zeros()).checked_sub(extra).unwrap(),
124-
sym::cttz => u128::from((bits << extra).trailing_zeros()).checked_sub(extra).unwrap(),
125-
sym::bswap => (bits << extra).swap_bytes(),
126-
sym::bitreverse => (bits << extra).reverse_bits(),
127-
_ => unreachable!(),
128-
};
129-
Scalar::from_uint(bits_out, size)
118+
this.numeric_intrinsic(name, op.to_scalar(), op.layout)?
130119
}
131120
};
132121
this.write_scalar(val, &dest)?;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#[path = "../../utils/mod.rs"]
2+
mod utils;
3+
4+
fn main() {
5+
let buffer = [0u32; 128];
6+
unsafe { utils::miri_promise_symbolic_alignment(buffer.as_ptr().cast(), 0) };
7+
//~^ERROR: alignment must be a power of 2
8+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: unsupported operation: `miri_promise_symbolic_alignment`: alignment must be a power of 2, got 0
2+
--> $DIR/promise_alignment_zero.rs:LL:CC
3+
|
4+
LL | unsafe { utils::miri_promise_symbolic_alignment(buffer.as_ptr().cast(), 0) };
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `miri_promise_symbolic_alignment`: alignment must be a power of 2, got 0
6+
|
7+
= help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support
8+
= note: BACKTRACE:
9+
= note: inside `main` at $DIR/promise_alignment_zero.rs:LL:CC
10+
11+
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
12+
13+
error: aborting due to 1 previous error
14+

‎src/tools/miri/tests/pass/align_offset_symbolic.rs‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,21 @@ fn test_cstr() {
9090
std::ffi::CStr::from_bytes_with_nul(b"this is a test that is longer than 16 bytes0円").unwrap();
9191
}
9292

93+
fn huge_align() {
94+
#[cfg(target_pointer_width = "64")]
95+
const SIZE: usize = 1 << 47;
96+
#[cfg(target_pointer_width = "32")]
97+
const SIZE: usize = 1 << 30;
98+
#[cfg(target_pointer_width = "16")]
99+
const SIZE: usize = 1 << 13;
100+
struct HugeSize([u8; SIZE - 1]);
101+
let _ = std::ptr::invalid::<HugeSize>(SIZE).align_offset(SIZE);
102+
}
103+
93104
fn main() {
94105
test_align_to();
95106
test_from_utf8();
96107
test_u64_array();
97108
test_cstr();
109+
huge_align();
98110
}

‎src/tools/miri/tests/pass/issues/issue-3200-packed2-field-offset.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ fn main() {
3030
unsafe {
3131
let p = PackedSized { f: 0, d: [1, 2, 3, 4] };
3232
let p = p.unsize() as *const PackedUnsized;
33-
// Make sure the size computation correctly adds exact 1 byte of padding
33+
// Make sure the size computation correctly adds exactly 1 byte of padding
3434
// in front of the `d` field.
3535
assert_eq!(mem::size_of_val_raw(p), 1 + 1 + 4 * 4);
3636
// And likewise for the offset computation.

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /