about summary refs log tree commit diff
path: root/src/libcore/ptr
diff options
context:
space:
mode:
authorcohenarthur <arthur.cohen@epita.fr>2020-04-23 22:32:20 +0200
committercohenarthur <arthur.cohen@epita.fr>2020-04-29 11:18:31 +0200
commit8558ccd5c4d3d7ca78aaff4a81c48f7a04b0f1f2 (patch)
tree77a4a3f3bcab9ee44f6ed067816edcdc9d3c5368 /src/libcore/ptr
parentb4a11d4dd971be4a2e055e4f92fece030615a692 (diff)
downloadrust-8558ccd5c4d3d7ca78aaff4a81c48f7a04b0f1f2.tar.gz
rust-8558ccd5c4d3d7ca78aaff4a81c48f7a04b0f1f2.zip
safety-ptr: Add SAFETY on some unsafe blocks from libcore/ptr
Add documentation example to slice_from_raw_parts_mut()
Add SAFETY explanations to some unsafe blocks in libcore/ptr

* libcore/ptr/mod.rs
* libcore/ptr/unique.rs
* libcore/ptr/non_null.rs

safety-mod.rs: Add SAFETY to slice_from_raw_parts(),
slice_from_raw_parts_mut()

slice_from_raw_parts_mut: Add documentation example

safety-ptr-unique.rs: Add SAFETY to new() and cast()

safety-ptr-non_null.rs: Add SAFETY to new()

safety-ptr-non_null.rs: Add SAFETY to cast()

safety-ptr-non_null.rs: Add SAFETY to from() impls

safety-ptr-unique.rs: Add SAFETY to from() impls

safety-ptr-non_null.rs: Add SAFETY to new()

safety-ptr-unique.rs: Add SAFETY to new()

safety-ptr-mod.rs: Fix safety explanation

https://github.com/rust-lang/rust/pull/71507#discussion_r414488884

safety-prt-non_null.rs: Fix SAFETY comment syntax

safety-ptr-unique.rs: Fix syntax for empty()

safety-ptr-non_null.rs: Fix misuse of non-null for align_of()

safety-ptr-non_null.rs: Remove incorrect SAFETY comment

safety-ptr-unique.rs: Remove unsound SAFETY comment

safety-ptr-mod.rs: Add std comment on slice_from_raw_parts guarantee

safety-ptr-unique.rs: Remove incorrect safety comment

Creating a Unique from a NonNull has strict guarantees that the current
implementation does not guarantee

https://github.com/rust-lang/rust/pull/71507#discussion_r415035952

safety-ptr: Re-adding ignore-tidy directive
Diffstat (limited to 'src/libcore/ptr')
-rw-r--r--src/libcore/ptr/mod.rs21
-rw-r--r--src/libcore/ptr/non_null.rs18
-rw-r--r--src/libcore/ptr/unique.rs7
3 files changed, 43 insertions, 3 deletions
diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs
index 54d44222d3f..58f779106f7 100644
--- a/src/libcore/ptr/mod.rs
+++ b/src/libcore/ptr/mod.rs
@@ -254,6 +254,9 @@ pub(crate) struct FatPtr<T> {
 #[stable(feature = "slice_from_raw_parts", since = "1.42.0")]
 #[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "67456")]
 pub const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
+    // SAFETY: Accessing the value from the `Repr` union is safe since *const [T]
+    // and FatPtr have the same memory layouts. Only std can make this
+    // guarantee.
     unsafe { Repr { raw: FatPtr { data, len } }.rust }
 }
 
@@ -267,10 +270,28 @@ pub const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
 ///
 /// [`slice_from_raw_parts`]: fn.slice_from_raw_parts.html
 /// [`from_raw_parts_mut`]: ../../std/slice/fn.from_raw_parts_mut.html
+///
+/// # Examples
+///
+/// ```rust
+/// use std::ptr;
+///
+/// let x = &mut [5, 6, 7];
+/// let raw_pointer = x.as_mut_ptr();
+/// let slice = ptr::slice_from_raw_parts_mut(raw_pointer, 3);
+///
+/// unsafe {
+///     (*slice)[2] = 99; // assign a value at an index in the slice
+/// };
+///
+/// assert_eq!(unsafe { &*slice }[2], 99);
+/// ```
 #[inline]
 #[stable(feature = "slice_from_raw_parts", since = "1.42.0")]
 #[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "67456")]
 pub const fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T] {
+    // SAFETY: Accessing the value from the `Repr` union is safe since *mut [T]
+    // and FatPtr have the same memory layouts
     unsafe { Repr { raw: FatPtr { data, len } }.rust_mut }
 }
 
diff --git a/src/libcore/ptr/non_null.rs b/src/libcore/ptr/non_null.rs
index 626e58d4930..7d08503215e 100644
--- a/src/libcore/ptr/non_null.rs
+++ b/src/libcore/ptr/non_null.rs
@@ -7,8 +7,6 @@ use crate::mem;
 use crate::ops::{CoerceUnsized, DispatchFromDyn};
 use crate::ptr::Unique;
 
-// ignore-tidy-undocumented-unsafe
-
 /// `*mut T` but non-zero and covariant.
 ///
 /// This is often the correct thing to use when building data structures using
@@ -69,6 +67,9 @@ impl<T: Sized> NonNull<T> {
     #[rustc_const_stable(feature = "const_nonnull_dangling", since = "1.32.0")]
     #[inline]
     pub const fn dangling() -> Self {
+        // SAFETY: mem::align_of() returns a non-zero usize which is then casted
+        // to a *mut T. Therefore, `ptr` is not null and the conditions for
+        // calling new_unchecked() are respected.
         unsafe {
             let ptr = mem::align_of::<T>() as *mut T;
             NonNull::new_unchecked(ptr)
@@ -93,7 +94,12 @@ impl<T: ?Sized> NonNull<T> {
     #[stable(feature = "nonnull", since = "1.25.0")]
     #[inline]
     pub fn new(ptr: *mut T) -> Option<Self> {
-        if !ptr.is_null() { Some(unsafe { Self::new_unchecked(ptr) }) } else { None }
+        if !ptr.is_null() {
+            // SAFETY: The pointer is already checked and is not null
+            Some(unsafe { Self::new_unchecked(ptr) })
+        } else {
+            None
+        }
     }
 
     /// Acquires the underlying `*mut` pointer.
@@ -131,6 +137,7 @@ impl<T: ?Sized> NonNull<T> {
     #[rustc_const_stable(feature = "const_nonnull_cast", since = "1.32.0")]
     #[inline]
     pub const fn cast<U>(self) -> NonNull<U> {
+        // SAFETY: `self` is a `NonNull` pointer which is necessarily non-null
         unsafe { NonNull::new_unchecked(self.as_ptr() as *mut U) }
     }
 }
@@ -205,6 +212,8 @@ impl<T: ?Sized> hash::Hash for NonNull<T> {
 impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
     #[inline]
     fn from(unique: Unique<T>) -> Self {
+        // SAFETY: A Unique pointer cannot be null, so the conditions for
+        // new_unchecked() are respected.
         unsafe { NonNull::new_unchecked(unique.as_ptr()) }
     }
 }
@@ -213,6 +222,7 @@ impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
 impl<T: ?Sized> From<&mut T> for NonNull<T> {
     #[inline]
     fn from(reference: &mut T) -> Self {
+        // SAFETY: A mutable reference cannot be null.
         unsafe { NonNull { pointer: reference as *mut T } }
     }
 }
@@ -221,6 +231,8 @@ impl<T: ?Sized> From<&mut T> for NonNull<T> {
 impl<T: ?Sized> From<&T> for NonNull<T> {
     #[inline]
     fn from(reference: &T) -> Self {
+        // SAFETY: A reference cannot be null, so the conditions for
+        // new_unchecked() are respected.
         unsafe { NonNull { pointer: reference as *const T } }
     }
 }
diff --git a/src/libcore/ptr/unique.rs b/src/libcore/ptr/unique.rs
index 87b56d951c6..7d823f91fec 100644
--- a/src/libcore/ptr/unique.rs
+++ b/src/libcore/ptr/unique.rs
@@ -74,6 +74,8 @@ impl<T: Sized> Unique<T> {
     // FIXME: rename to dangling() to match NonNull?
     #[inline]
     pub const fn empty() -> Self {
+        // SAFETY: mem::align_of() returns a valid, non-null pointer. The
+        // conditions to call new_unchecked() are thus respected.
         unsafe { Unique::new_unchecked(mem::align_of::<T>() as *mut T) }
     }
 }
@@ -94,6 +96,7 @@ impl<T: ?Sized> Unique<T> {
     #[inline]
     pub fn new(ptr: *mut T) -> Option<Self> {
         if !ptr.is_null() {
+            // SAFETY: The pointer has already been checked and is not null.
             Some(unsafe { Unique { pointer: ptr as _, _marker: PhantomData } })
         } else {
             None
@@ -129,6 +132,9 @@ impl<T: ?Sized> Unique<T> {
     /// Casts to a pointer of another type.
     #[inline]
     pub const fn cast<U>(self) -> Unique<U> {
+        // SAFETY: Unique::new_unchecked() creates a new unique and needs
+        // the given pointer to not be null.
+        // Since we are passing self as a pointer, it cannot be null.
         unsafe { Unique::new_unchecked(self.as_ptr() as *mut U) }
     }
 }
@@ -168,6 +174,7 @@ impl<T: ?Sized> fmt::Pointer for Unique<T> {
 impl<T: ?Sized> From<&mut T> for Unique<T> {
     #[inline]
     fn from(reference: &mut T) -> Self {
+        // SAFETY: A mutable reference cannot be null
         unsafe { Unique { pointer: reference as *mut T, _marker: PhantomData } }
     }
 }