@@ -27,9 +27,12 @@ Please read the [Rustonomicon] before writing unsafe code.
2727</div >
2828
2929* Data races.
30- * Evaluating a [ dereference expression] (` *expr ` ) on a raw pointer that is
31- [ dangling] or unaligned, even in [ place expression context]
32- (e.g. ` addr_of!(*expr) ` ).
30+ * Accessing (loading from or storing to) a place that is [ dangling] or [ based on
31+ a misaligned pointer] .
32+ * Performing a place projection that violates the requirements of [ in-bounds
33+ pointer arithmetic] [ offset ] . A place projection is a [ field
34+ expression] [ project-field ] , a [ tuple index expression] [ project-tuple ] , or an
35+ [ array/slice index expression] [ project-slice ] .
3336* Breaking the [ pointer aliasing rules] . ` Box<T> ` , ` &mut T ` and ` &T ` follow
3437 LLVM’s scoped [ noalias] model, except if the ` &T ` contains an
3538 [ ` UnsafeCell<U> ` ] . References and boxes must not be [ dangling] while they are
@@ -68,7 +71,7 @@ Please read the [Rustonomicon] before writing unsafe code.
6871 * A ` ! ` (all values are invalid for this type).
6972 * An integer (` i* ` /` u* ` ), floating point value (` f* ` ), or raw pointer obtained
7073 from [ uninitialized memory] [ undef ] , or uninitialized memory in a ` str ` .
71- * A reference or ` Box<T> ` that is [ dangling] , unaligned , or points to an invalid value.
74+ * A reference or ` Box<T> ` that is [ dangling] , misaligned , or points to an invalid value.
7275 * Invalid metadata in a wide reference, ` Box<T> ` , or raw pointer:
7376 * ` dyn Trait ` metadata is invalid if it is not a pointer to a vtable for
7477 ` Trait ` that matches the actual dynamic trait the pointer or reference points to.
@@ -102,6 +105,36 @@ reading uninitialized memory is permitted are inside `union`s and in "padding"
102105
103106The span of bytes a pointer or reference "points to" is determined by the pointer value and the size of the pointee type (using ` size_of_val ` ).
104107
108+ ### Places based on misaligned pointers
109+ [ based on a misaligned pointer ] : #places-based-on-misaligned-pointers
110+
111+ A place is said to be "based on a misaligned pointer" if the last ` * ` projection
112+ during place computation was performed on a pointer that was not aligned for its
113+ type. (If there is no ` * ` projection in the place expression, then this is
114+ accessing the field of a local and rustc will guarantee proper alignment. If
115+ there are multiple ` * ` projection, then each of them incurs a load of the
116+ pointer-to-be-dereferenced itself from memory, and each of these loads is
117+ subject to the alignment constraint. Note that some ` * ` projections can be
118+ omitted in surface Rust syntax due to automatic dereferencing; we are
119+ considering the fully expanded place expression here.)
120+
121+ For instance, if ` ptr ` has type ` *const S ` where ` S ` has an alignment of 8, then
122+ ` ptr ` must be 8-aligned or else ` (*ptr).f ` is "based on an misaligned pointer".
123+ This is true even if the type of the field ` f ` is ` u8 ` (i.e., a type with
124+ alignment 1). In other words, the alignment requirement derives from the type of
125+ the pointer that was dereferenced, * not* the type of the field that is being
126+ accessed.
127+
128+ Note that a place based on a misaligned pointer only leads to Undefined Behavior
129+ when it is loaded from or stored to. ` addr_of! ` /` addr_of_mut! ` on such a place
130+ is allowed. ` & ` /` &mut ` on a place requires the alignment of the field type (or
131+ else the program would be "producing an invalid value"), which generally is a
132+ less restrictive requirement than being based on an aligned pointer. Taking a
133+ reference will lead to a compiler error in cases where the field type might be
134+ more aligned than the type that contains it, i.e., ` repr(packed) ` . This means
135+ that being based on an aligned pointer is always sufficient to ensure that the
136+ new reference is aligned, but it is not always necessary.
137+
105138### Dangling pointers
106139[ dangling ] : #dangling-pointers
107140
@@ -128,8 +161,11 @@ must never exceed `isize::MAX`.
128161[ Rustonomicon ] : ../nomicon/index.html
129162[ `NonNull<T>` ] : ../core/ptr/struct.NonNull.html
130163[ `NonZero*` ] : ../core/num/index.html
131- [ dereference expression ] : expressions/operator-expr.md#the-dereference-operator
132164[ place expression context ] : expressions.md#place-expressions-and-value-expressions
133165[ rules ] : inline-assembly.md#rules-for-inline-assembly
134166[ points to ] : #pointed-to-bytes
135167[ pointed to ] : #pointed-to-bytes
168+ [ offset ] : ../std/primitive.pointer.html#method.offset
169+ [ project-field ] : expressions/field-expr.md
170+ [ project-tuple ] : expressions/tuple-expr.md#tuple-indexing-expressions
171+ [ project-slice ] : expressions/array-expr.md#array-and-slice-indexing-expressions
0 commit comments