Skip to content

Commit aabdd7d

Browse files
committed
zero-sized accesses are fine on null pointers
1 parent 63a4a9b commit aabdd7d

File tree

3 files changed

+16
-13
lines changed

3 files changed

+16
-13
lines changed

core/src/intrinsics.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -3138,7 +3138,7 @@ pub const fn ptr_metadata<P: ptr::Pointee<Metadata = M> + ?Sized, M>(_ptr: *cons
31383138
/// [violate memory safety][read-ownership].
31393139
///
31403140
/// Note that even if the effectively copied size (`count * size_of::<T>()`) is
3141-
/// `0`, the pointers must be non-null and properly aligned.
3141+
/// `0`, the pointers must be properly aligned.
31423142
///
31433143
/// [`read`]: crate::ptr::read
31443144
/// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value
@@ -3261,7 +3261,7 @@ pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: us
32613261
/// [violate memory safety][read-ownership].
32623262
///
32633263
/// Note that even if the effectively copied size (`count * size_of::<T>()`) is
3264-
/// `0`, the pointers must be non-null and properly aligned.
3264+
/// `0`, the pointers must be properly aligned.
32653265
///
32663266
/// [`read`]: crate::ptr::read
32673267
/// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value
@@ -3342,7 +3342,7 @@ pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
33423342
/// * `dst` must be properly aligned.
33433343
///
33443344
/// Note that even if the effectively copied size (`count * size_of::<T>()`) is
3345-
/// `0`, the pointer must be non-null and properly aligned.
3345+
/// `0`, the pointer must be properly aligned.
33463346
///
33473347
/// Additionally, note that changing `*dst` in this way can easily lead to undefined behavior (UB)
33483348
/// later if the written bytes are not a valid representation of some `T`. For instance, the

core/src/primitive_docs.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -505,9 +505,11 @@ impl () {}
505505
///
506506
/// *[See also the `std::ptr` module](ptr).*
507507
///
508-
/// Working with raw pointers in Rust is uncommon, typically limited to a few patterns.
509-
/// Raw pointers can be unaligned or [`null`]. However, when a raw pointer is
510-
/// dereferenced (using the `*` operator), it must be non-null and aligned.
508+
/// Working with raw pointers in Rust is uncommon, typically limited to a few patterns. Raw pointers
509+
/// can be out-of-bounds, unaligned, or [`null`]. However, when loading from or storing to a raw
510+
/// pointer, it must be [valid] for the given access and aligned. When using a field expression,
511+
/// tuple index expression, or array/slice index expression on a raw pointer, it follows the rules
512+
/// of [in-bounds pointer arithmetic][`offset`].
511513
///
512514
/// Storing through a raw pointer using `*ptr = data` calls `drop` on the old value, so
513515
/// [`write`] must be used if the type has drop glue and memory is not already
@@ -613,6 +615,7 @@ impl () {}
613615
/// [`offset`]: pointer::offset
614616
/// [`into_raw`]: ../std/boxed/struct.Box.html#method.into_raw
615617
/// [`write`]: ptr::write
618+
/// [valid]: ptr#safety
616619
#[stable(feature = "rust1", since = "1.0.0")]
617620
mod prim_pointer {}
618621

core/src/ptr/mod.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -1024,7 +1024,7 @@ pub const fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T] {
10241024
///
10251025
/// * Both `x` and `y` must be properly aligned.
10261026
///
1027-
/// Note that even if `T` has size `0`, the pointers must be non-null and properly aligned.
1027+
/// Note that even if `T` has size `0`, the pointers must be properly aligned.
10281028
///
10291029
/// [valid]: self#safety
10301030
///
@@ -1110,7 +1110,7 @@ pub const unsafe fn swap<T>(x: *mut T, y: *mut T) {
11101110
/// beginning at `y` with the same size.
11111111
///
11121112
/// Note that even if the effectively copied size (`count * size_of::<T>()`) is `0`,
1113-
/// the pointers must be non-null and properly aligned.
1113+
/// the pointers must be properly aligned.
11141114
///
11151115
/// [valid]: self#safety
11161116
///
@@ -1243,7 +1243,7 @@ const unsafe fn swap_nonoverlapping_simple_untyped<T>(x: *mut T, y: *mut T, coun
12431243
///
12441244
/// * `dst` must point to a properly initialized value of type `T`.
12451245
///
1246-
/// Note that even if `T` has size `0`, the pointer must be non-null and properly aligned.
1246+
/// Note that even if `T` has size `0`, the pointer must be properly aligned.
12471247
///
12481248
/// [valid]: self#safety
12491249
///
@@ -1300,7 +1300,7 @@ pub const unsafe fn replace<T>(dst: *mut T, src: T) -> T {
13001300
///
13011301
/// * `src` must point to a properly initialized value of type `T`.
13021302
///
1303-
/// Note that even if `T` has size `0`, the pointer must be non-null and properly aligned.
1303+
/// Note that even if `T` has size `0`, the pointer must be properly aligned.
13041304
///
13051305
/// # Examples
13061306
///
@@ -1555,7 +1555,7 @@ pub const unsafe fn read_unaligned<T>(src: *const T) -> T {
15551555
/// * `dst` must be properly aligned. Use [`write_unaligned`] if this is not the
15561556
/// case.
15571557
///
1558-
/// Note that even if `T` has size `0`, the pointer must be non-null and properly aligned.
1558+
/// Note that even if `T` has size `0`, the pointer must be properly aligned.
15591559
///
15601560
/// [valid]: self#safety
15611561
///
@@ -1774,7 +1774,7 @@ pub const unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
17741774
/// However, storing non-[`Copy`] types in volatile memory is almost certainly
17751775
/// incorrect.
17761776
///
1777-
/// Note that even if `T` has size `0`, the pointer must be non-null and properly aligned.
1777+
/// Note that even if `T` has size `0`, the pointer must be properly aligned.
17781778
///
17791779
/// [valid]: self#safety
17801780
/// [read-ownership]: read#ownership-of-the-returned-value
@@ -1853,7 +1853,7 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
18531853
///
18541854
/// * `dst` must be properly aligned.
18551855
///
1856-
/// Note that even if `T` has size `0`, the pointer must be non-null and properly aligned.
1856+
/// Note that even if `T` has size `0`, the pointer must be properly aligned.
18571857
///
18581858
/// [valid]: self#safety
18591859
///

0 commit comments

Comments
 (0)