Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
911d35f
Rewrite docs for `std::ptr`
ecstatic-morse Apr 6, 2018
da58beb
Mention alignment in top-level docs
May 24, 2018
9f5a3cc
Fix failing doctests
ecstatic-morse May 24, 2018
04a08c6
Fix unused variable warning in doctest
ecstatic-morse May 24, 2018
7b2ef6b
Update docs for `swap_nonoverlapping`
ecstatic-morse May 29, 2018
6f7338b
Reword module level docs re: alignment
ecstatic-morse Jun 5, 2018
30122e9
Fix off-by-one error when specifying a valid range
ecstatic-morse Jun 5, 2018
e40585f
Remove definiton of valid pointer
ecstatic-morse Jun 15, 2018
ea5570c
Redefine range validity
ecstatic-morse Jun 16, 2018
3a55c85
Incorporate RalfJung's suggestions
ecstatic-morse Jun 17, 2018
95a9088
You can't make an omlette without breaking a few links
ecstatic-morse Jun 17, 2018
7e165d9
Add a list of known facts re: validity
ecstatic-morse Jul 4, 2018
c8da321
Resolve null/ZST conflict correctly (whoops)
ecstatic-morse Jul 4, 2018
b0c5dc2
edit docs a little
RalfJung Aug 29, 2018
098bec8
clarify that these are preliminary guarantees
RalfJung Aug 29, 2018
fc63113
clarify ZST comment
RalfJung Aug 30, 2018
1ec66fb
apply comments
RalfJung Aug 30, 2018
e869b81
address remaining remarks and add example for dropping unaligned data
RalfJung Aug 30, 2018
d97f61f
avoid shadowing; fix examples
RalfJung Aug 30, 2018
c06f551
improve volatile comments
RalfJung Aug 30, 2018
2741224
fix example
RalfJung Aug 30, 2018
18a7bdb
fix example
RalfJung Aug 30, 2018
4ed469c
turn ptr type method docs into links to docs of free functions, to av…
RalfJung Aug 31, 2018
dc2237c
apply feedback
RalfJung Aug 31, 2018
b463871
(un)aligned
RalfJung Aug 31, 2018
408a6a0
fix doctests
RalfJung Aug 31, 2018
755de3c
Valid raw pointers
RalfJung Sep 1, 2018
bc809e0
remark on concurrency in validity section
RalfJung Sep 1, 2018
78f5b68
fix typos
ubsan Sep 11, 2018
c44e88c
Merge pull request #1 from ubsan/ptr-docs
RalfJung Sep 11, 2018
2713d36
tweaks
RalfJung Sep 17, 2018
0ec87d0
rearrange for clarity
RalfJung Sep 17, 2018
adcc0d2
clarify swap
RalfJung Sep 18, 2018
c197dc4
clarify write_bytes a bit
RalfJung Sep 21, 2018
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Incorporate RalfJung's suggestions
This splits "valid" into "valid for reads" and "valid for writes", and also adds the concept of operation size to validity. Now functions which operate on sequences state that e.g. pointer args must be "valid for reads of size x".
  • Loading branch information
ecstatic-morse authored and RalfJung committed Aug 29, 2018
commit 3a55c85c33ec1ed5222ff7f9c57ce8fc426d9455
35 changes: 11 additions & 24 deletions src/libcore/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -976,19 +976,15 @@ extern "rust-intrinsic" {
///
/// Behavior is undefined if any of the following conditions are violated:
///
/// * Both `src` and `dst` must be properly aligned.
/// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
///
/// * `src.offset(i)` must be [valid] for all `i` in `0..count`. In other
/// words, the region of memory which begins at `src` and has a length of
/// `count * size_of::<T>()` bytes must belong to a single, live
/// allocation.
/// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
///
/// * `dst.offset(i)` must be [valid] for all `i` in `0..count`. In other
/// words, the region of memory which begins at `dst` and has a length of
/// `count * size_of::<T>()` bytes must belong to a single, live
/// allocation.
/// * Both `src` and `dst` must be properly aligned.
///
/// * The two regions of memory must *not* overlap.
/// * The region of memory beginning at `src` with a size of `count *
/// size_of::<T>()` bytes must *not* overlap with the region of memory
/// beginning at `dst` with the same size.
///
/// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of
/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values
Expand Down Expand Up @@ -1064,17 +1060,11 @@ extern "rust-intrinsic" {
///
/// Behavior is undefined if any of the following conditions are violated:
///
/// * Both `src` and `dst` must be properly aligned.
/// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
///
/// * `src.offset(i)` must be [valid] for all `i` in `0..count`. In other
/// words, the region of memory which begins at `src` and has a length of
/// `count * size_of::<T>()` bytes must belong to a single, live
/// allocation.
/// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
///
/// * `dst.offset(i)` must be [valid] for all `i` in `0..count`. In other
/// words, the region of memory which begins at `dst` and has a length of
/// `count * size_of::<T>()` bytes must belong to a single, live
/// allocation.
/// * Both `src` and `dst` must be properly aligned.
///
/// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of
/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values
Expand Down Expand Up @@ -1116,12 +1106,9 @@ extern "rust-intrinsic" {
///
/// Behavior is undefined if any of the following conditions are violated:
///
/// * `dst` must be properly aligned.
/// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
///
/// * `dst.offset(i)` must be [valid] for all `i` in `0..count`. In other
/// words, the region of memory which begins at `dst` and has a length of
/// `count * size_of::<T>()` bytes must belong to a single, live
/// allocation.
/// * `dst` must be properly aligned.
///
/// Additionally, the caller must ensure that writing `count *
/// size_of::<T>()` bytes to the given region of memory results in a valid
Expand Down
66 changes: 38 additions & 28 deletions src/libcore/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,38 @@
//! Many functions in this module take raw pointers as arguments and dereference
//! them. For this to be safe, these pointers must be valid. However, because
//! rust does not yet have a formal memory model, determining whether an
//! arbitrary pointer is a valid one can be tricky. One thing is certain:
//! creating a raw pointer from a reference (e.g. `&x as *const _`) *always*
//! results in a valid pointer. By exploiting this—and by taking care when
//! using [pointer arithmetic]—users can be confident in the correctness of
//! their unsafe code.
//! arbitrary pointer is valid for a given operation can be tricky.
//!
//! For more information on dereferencing raw pointers, see the both the [book]
//! and the section in the reference devoted to [undefined behavior][ub].
//! There are two types of operations on memory, reads and writes. It is
//! possible for a `*mut` to be valid for one operation and not the other. Since
//! a `*const` can only be read and not written, it has no such ambiguity. For
//! example, a `*mut` is not valid for writes if a a reference exists which
//! [refers to the same memory][aliasing]. Therefore, each function in this
//! module will document which operations must be valid on any `*mut` arguments.
//!
//! Additionally, some functions (e.g. [`copy`]) take a single pointer but
//! operate on many values. In this case, the function will state the size of
//! the operation for which the pointer must be valid. For example,
//! `copy::<T>(&src, &mut dst, 3)` requires `dst` to be valid for writes of
//! `size_of::<T>() * 3` bytes. When the documentation requires that a pointer
//! be valid for an operation but omits the size of that operation, the size is
//! implied to be `size_of::<T>()` bytes.
//!
//! For more information on the safety implications of dereferencing raw
//! pointers, see the both the [book] and the section in the reference devoted
//! to [undefined behavior][ub].
//!
//! ## Alignment
//!
//! Valid pointers are not necessarily properly aligned. However, most functions
//! require their arguments to be properly aligned, and will explicitly state
//! this requirement in the `Safety` section. Notable exceptions to this are
//! this requirement in their documentation. Notable exceptions to this are
//! [`read_unaligned`] and [`write_unaligned`].
//!
//! [ub]: ../../reference/behavior-considered-undefined.html
//! [aliasing]: ../../nomicon/aliasing.html
//! [book]: ../../book/second-edition/ch19-01-unsafe-rust.html#dereferencing-a-raw-pointer
//! [pointer arithmetic]: ../../std/primitive.pointer.html#method.offset
//! [ub]: ../../reference/behavior-considered-undefined.html
//! [`copy`]: ./fn.copy.html
//! [`read_unaligned`]: ./fn.read_unaligned.html
//! [`write_unaligned`]: ./fn.write_unaligned.html

Expand Down Expand Up @@ -83,7 +96,7 @@ pub use intrinsics::write_bytes;
///
/// Behavior is undefined if any of the following conditions are violated:
///
/// * `to_drop` must be [valid].
/// * `to_drop` must be [valid] for reads.
///
/// * `to_drop` must be properly aligned.
///
Expand Down Expand Up @@ -178,7 +191,7 @@ pub const fn null_mut<T>() -> *mut T { 0 as *mut T }
///
/// Behavior is undefined if any of the following conditions are violated:
///
/// * Both `x` and `y` must be [valid].
/// * Both `x` and `y` must be [valid] for reads and writes.
///
/// * Both `x` and `y` must be properly aligned.
///
Expand Down Expand Up @@ -240,17 +253,14 @@ pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
///
/// Behavior is undefined if any of the following conditions are violated:
///
/// * Both `x` and `y` must be properly aligned.
///
/// * `x.offset(i)` must be [valid] for all `i` in `0..count`. In other words,
/// the region of memory which begins at `x` and has a length of `count *
/// size_of::<T>()` bytes must belong to a single, live allocation.
/// * Both `x` and `y` must be [valid] for reads and writes of `count *
/// size_of::<T>()` bytes.
///
/// * `y.offset(i)` must be [valid] for all `i` in `0..count`. In other words,
/// the region of memory which begins at `y` and has a length of `count *
/// size_of::<T>()` bytes must belong to a single, live allocation.
/// * Both `x` and `y` must be properly aligned.
///
/// * The two regions of memory must *not* overlap.
/// * The region of memory beginning at `x` with a size of `count *
/// size_of::<T>()` bytes must *not* overlap with the region of memory
/// beginning at `y` with the same size.
///
/// [valid]: ../ptr/index.html#safety
///
Expand Down Expand Up @@ -359,7 +369,7 @@ unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) {
///
/// Behavior is undefined if any of the following conditions are violated:
///
/// * `dest` must be [valid].
/// * `dest` must be [valid] for writes.
///
/// * `dest` must be properly aligned.
///
Expand Down Expand Up @@ -395,7 +405,7 @@ pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
///
/// Behavior is undefined if any of the following conditions are violated:
///
/// * `src` must be [valid].
/// * `src` must be [valid] for reads.
///
/// * `src` must be properly aligned. Use [`read_unaligned`] if this is not the
/// case.
Expand Down Expand Up @@ -508,7 +518,7 @@ pub unsafe fn read<T>(src: *const T) -> T {
///
/// Behavior is undefined if any of the following conditions are violated:
///
/// * `src` must be [valid].
/// * `src` must be [valid] for reads.
///
/// Like [`read`], `read_unaligned` creates a bitwise copy of `T`, regardless of
/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the returned
Expand Down Expand Up @@ -585,7 +595,7 @@ pub unsafe fn read_unaligned<T>(src: *const T) -> T {
///
/// Behavior is undefined if any of the following conditions are violated:
///
/// * `dst` must be [valid].
/// * `dst` must be [valid] for writes.
///
/// * `dst` must be properly aligned. Use [`write_unaligned`] if this is not the
/// case.
Expand Down Expand Up @@ -659,7 +669,7 @@ pub unsafe fn write<T>(dst: *mut T, src: T) {
///
/// Behavior is undefined if any of the following conditions are violated:
///
/// * `dst` must be [valid].
/// * `dst` must be [valid] for writes.
///
/// [valid]: ../ptr/index.html#safety
///
Expand Down Expand Up @@ -734,7 +744,7 @@ pub unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
///
/// Behavior is undefined if any of the following conditions are violated:
///
/// * `src` must be [valid].
/// * `src` must be [valid] for reads.
///
/// * `src` must be properly aligned.
///
Expand Down Expand Up @@ -809,7 +819,7 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
///
/// Behavior is undefined if any of the following conditions are violated:
///
/// * `dst` must be [valid].
/// * `dst` must be [valid] for writes.
///
/// * `dst` must be properly aligned.
///
Expand Down