From 7cbdc9cc80ce221a8052b906eca0268bcd1d5987 Mon Sep 17 00:00:00 2001 From: Jack Wrenn Date: Wed, 25 Oct 2023 20:44:15 +0000 Subject: [PATCH] constrain safety preconditions of `layout_for_ptr` functionality This commit implements the recommendation of [1] to make the safety preconditions of the raw pointer layout utilities more conservative, to ease the path towards stabilization. In the future, we may (if we choose) remove some of these restrictions without breaking forwards compatibility. [1]: https://github.com/rust-lang/rust/issues/69835#issuecomment-1779590064 --- library/core/src/alloc/layout.rs | 4 ++++ library/core/src/mem/mod.rs | 12 ++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs index 65946e09ff9ba..0e0d7d948f247 100644 --- a/library/core/src/alloc/layout.rs +++ b/library/core/src/alloc/layout.rs @@ -181,10 +181,14 @@ 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`. + /// The pointer address plus the size of the entire value must not + /// overflow the address space. /// - 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* /// (dynamic tail length + statically sized prefix) must fit in `isize`. + /// The pointer address plus the size of the entire value must not + /// overflow the address space. /// - an (unstable) [extern type], then this function is always safe to /// call, but may panic or otherwise return the wrong value, as the /// extern type's layout is not known. This is the same behavior as diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index a79a204e2c6a0..f1d358ffe044d 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -359,10 +359,13 @@ pub const fn size_of_val(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`. +/// The pointer address plus the size of the entire value must not +/// overflow the address space. /// - 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) -/// must fit in `isize`. +/// must fit in `isize`. The pointer address plus the size of the entire +/// value must not overflow the address space. /// - an (unstable) [extern type], then this function is always safe to /// call, but may panic or otherwise return the wrong value, as the /// extern type's layout is not known. This is the same behavior as @@ -506,10 +509,15 @@ pub const fn align_of_val(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`. +/// The pointer address plus the size of the entire value must not +/// overflow the address space. The value one-past-the-end of this range +/// must also be within the address space. /// - 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) -/// must fit in `isize`. +/// must fit in `isize`. The pointer address plus the size of the entire +/// value must not overflow the address space. The value one-past-the-end +/// of this range must also be within the address space. /// - an (unstable) [extern type], then this function is always safe to /// call, but may panic or otherwise return the wrong value, as the /// extern type's layout is not known. This is the same behavior as