about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMark Rousskov <mark.simulacrum@gmail.com>2018-07-24 16:43:50 -0600
committerGitHub <noreply@github.com>2018-07-24 16:43:50 -0600
commit4bb8c31f101e93011af22d3c5ed9abd9c0fb15f9 (patch)
treec2ecf4e6a64db6b5a052167022b616a14dcb3cbe
parentc7a178ea5f84620508efbee96fb1da287c1a779d (diff)
parentfb089156220ec2932b11de21226296c7fe3503f3 (diff)
downloadrust-4bb8c31f101e93011af22d3c5ed9abd9c0fb15f9.tar.gz
rust-4bb8c31f101e93011af22d3c5ed9abd9c0fb15f9.zip
Rollup merge of #52668 - RalfJung:ptr-doc, r=cramertj
clarify pointer offset function safety concerns
-rw-r--r--src/libcore/ptr.rs20
1 files changed, 16 insertions, 4 deletions
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index d020e14be4c..be82ab44cd1 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -591,7 +591,7 @@ impl<T: ?Sized> *const T {
     /// Behavior:
     ///
     /// * Both the starting and resulting pointer must be either in bounds or one
-    ///   byte past the end of an allocated object.
+    ///   byte past the end of *the same* allocated object.
     ///
     /// * The computed offset, **in bytes**, cannot overflow an `isize`.
     ///
@@ -643,9 +643,15 @@ impl<T: ?Sized> *const T {
     ///
     /// The resulting pointer does not need to be in bounds, but it is
     /// potentially hazardous to dereference (which requires `unsafe`).
+    /// In particular, the resulting pointer may *not* be used to access a
+    /// different allocated object than the one `self` points to. In other
+    /// words, `x.wrapping_offset(y.wrapping_offset_from(x))` is
+    /// *not* the same as `y`, and dereferencing it is undefined behavior
+    /// unless `x` and `y` point into the same allocated object.
     ///
     /// Always use `.offset(count)` instead when possible, because `offset`
-    /// allows the compiler to optimize better.
+    /// allows the compiler to optimize better.  If you need to cross object
+    /// boundaries, cast the pointer to an integer and do the arithmetic there.
     ///
     /// # Examples
     ///
@@ -1340,7 +1346,7 @@ impl<T: ?Sized> *mut T {
     /// Behavior:
     ///
     /// * Both the starting and resulting pointer must be either in bounds or one
-    ///   byte past the end of an allocated object.
+    ///   byte past the end of *the same* allocated object.
     ///
     /// * The computed offset, **in bytes**, cannot overflow an `isize`.
     ///
@@ -1391,9 +1397,15 @@ impl<T: ?Sized> *mut T {
     ///
     /// The resulting pointer does not need to be in bounds, but it is
     /// potentially hazardous to dereference (which requires `unsafe`).
+    /// In particular, the resulting pointer may *not* be used to access a
+    /// different allocated object than the one `self` points to. In other
+    /// words, `x.wrapping_offset(y.wrapping_offset_from(x))` is
+    /// *not* the same as `y`, and dereferencing it is undefined behavior
+    /// unless `x` and `y` point into the same allocated object.
     ///
     /// Always use `.offset(count)` instead when possible, because `offset`
-    /// allows the compiler to optimize better.
+    /// allows the compiler to optimize better.  If you need to cross object
+    /// boundaries, cast the pointer to an integer and do the arithmetic there.
     ///
     /// # Examples
     ///