From aa04dc1eeb53e90ee8473648610945a08232e56f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 27 Mar 2022 20:01:04 -0400 Subject: [PATCH] Rust values can be up to isize::MAX in size --- src/shims/intrinsics.rs | 2 ++ tests/compile-fail/too-big-unsized.rs | 7 +------ tests/run-pass/slices.rs | 9 +++++++++ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/shims/intrinsics.rs b/src/shims/intrinsics.rs index c344d0ff9c3..7e2068e4657 100644 --- a/src/shims/intrinsics.rs +++ b/src/shims/intrinsics.rs @@ -83,6 +83,8 @@ fn call_intrinsic( let val_byte = this.read_scalar(val_byte)?.to_u8()?; let ptr = this.read_pointer(ptr)?; let count = this.read_scalar(count)?.to_machine_usize(this)?; + // `checked_mul` enforces a too small bound (the correct one would probably be machine_isize_max), + // but no actual allocation can be big enough for the difference to be noticeable. let byte_count = ty_layout.size.checked_mul(count, this).ok_or_else(|| { err_ub_format!("overflow computing total size of `{}`", intrinsic_name) })?; diff --git a/tests/compile-fail/too-big-unsized.rs b/tests/compile-fail/too-big-unsized.rs index ad7bc6e938a..824190a66ee 100644 --- a/tests/compile-fail/too-big-unsized.rs +++ b/tests/compile-fail/too-big-unsized.rs @@ -6,13 +6,8 @@ struct MySlice { tail: [u8], } -#[cfg(target_pointer_width = "64")] -const TOO_BIG: usize = 1usize << 47; -#[cfg(target_pointer_width = "32")] -const TOO_BIG: usize = 1usize << 31; - fn main() { unsafe { let ptr = Box::into_raw(Box::new(0u8)); // The slice part is actually not "too big", but together with the `prefix` field it is. - let _x: &MySlice = mem::transmute((ptr, TOO_BIG-1)); //~ ERROR: invalid reference metadata: total size is bigger than largest supported object + let _x: &MySlice = mem::transmute((ptr, isize::MAX as usize)); //~ ERROR: invalid reference metadata: total size is bigger than largest supported object } } diff --git a/tests/run-pass/slices.rs b/tests/run-pass/slices.rs index 9d98c44741b..bf3585f74e9 100644 --- a/tests/run-pass/slices.rs +++ b/tests/run-pass/slices.rs @@ -2,6 +2,7 @@ #![feature(new_uninit)] #![feature(slice_as_chunks)] #![feature(slice_partition_dedup)] +#![feature(layout_for_ptr)] use std::slice; @@ -250,9 +251,17 @@ fn test_for_invalidated_pointers() { buffer.copy_within(1.., 0); } +fn large_raw_slice() { + let size = isize::MAX as usize; + // Creating a raw slice of size isize::MAX and asking for its size is okay. + let s = std::ptr::slice_from_raw_parts(1usize as *const u8, size); + assert_eq!(size, unsafe { std::mem::size_of_val_raw(s) }); +} + fn main() { slice_of_zst(); test_iter_ref_consistency(); uninit_slice(); test_for_invalidated_pointers(); + large_raw_slice(); }