Skip to content

Commit

Permalink
Rollup merge of rust-lang#126152 - RalfJung:size_of_val_raw, r=saethlin
Browse files Browse the repository at this point in the history
size_of_val_raw: for length 0 this is safe to call

For motivation, see rust-lang/unsafe-code-guidelines#465, specifically around [here](rust-lang/unsafe-code-guidelines#465 (comment)).
Cc `@rust-lang/opsem`
  • Loading branch information
matthiaskrgr authored Jul 24, 2024
2 parents 2ccafed + 287b66b commit 130d15e
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 0 deletions.
2 changes: 2 additions & 0 deletions library/core/src/alloc/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,8 @@ impl Layout {
/// - a [slice], then the length of the slice tail must be an initialized
/// integer, and the size of the *entire value*
/// (dynamic tail length + statically sized prefix) must fit in `isize`.
/// For the special case where the dynamic tail length is 0, this function
/// is safe to call.
/// - a [trait object], then the vtable part of the pointer must point
/// to a valid vtable for the type `T` acquired by an unsizing coercion,
/// and the size of the *entire value*
Expand Down
8 changes: 8 additions & 0 deletions library/core/src/mem/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,12 @@ pub const fn size_of_val<T: ?Sized>(val: &T) -> usize {
/// - a [slice], then the length of the slice tail must be an initialized
/// integer, and the size of the *entire value*
/// (dynamic tail length + statically sized prefix) must fit in `isize`.
/// For the special case where the dynamic tail length is 0, this function
/// is safe to call.
// NOTE: the reason this is safe is that if an overflow were to occur already with size 0,
// then we would stop compilation as even the "statically known" part of the type would
// already be too big (or the call may be in dead code and optimized away, but then it
// doesn't matter).
/// - a [trait object], then the vtable part of the pointer must point
/// to a valid vtable acquired by an unsizing coercion, and the size
/// of the *entire value* (dynamic tail length + statically sized prefix)
Expand Down Expand Up @@ -506,6 +512,8 @@ pub const fn align_of_val<T: ?Sized>(val: &T) -> usize {
/// - a [slice], then the length of the slice tail must be an initialized
/// integer, and the size of the *entire value*
/// (dynamic tail length + statically sized prefix) must fit in `isize`.
/// For the special case where the dynamic tail length is 0, this function
/// is safe to call.
/// - a [trait object], then the vtable part of the pointer must point
/// to a valid vtable acquired by an unsizing coercion, and the size
/// of the *entire value* (dynamic tail length + statically sized prefix)
Expand Down
18 changes: 18 additions & 0 deletions tests/ui/layout/size-of-val-raw-too-big.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//@ build-fail
//@ compile-flags: --crate-type lib
//@ only-32bit Layout computation rejects this layout for different reasons on 64-bit.
//@ error-pattern: too big for the current architecture
#![feature(core_intrinsics)]
#![allow(internal_features)]

// isize::MAX is fine, but with the padding for the unsized tail it is too big.
#[repr(C)]
pub struct Example([u8; isize::MAX as usize], [u16]);

// We guarantee that with length 0, `size_of_val_raw` (which calls the `size_of_val` intrinsic)
// is safe to call. The compiler aborts compilation if a length of 0 would overflow.
// So let's construct a case where length 0 just barely overflows, and ensure that
// does abort compilation.
pub fn check(x: *const Example) -> usize {
unsafe { std::intrinsics::size_of_val(x) }
}
4 changes: 4 additions & 0 deletions tests/ui/layout/size-of-val-raw-too-big.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
error: values of the type `Example` are too big for the current architecture

error: aborting due to 1 previous error

0 comments on commit 130d15e

Please sign in to comment.