@@ -27,9 +27,12 @@ Please read the [Rustonomicon] before writing unsafe code.
27
27
</div >
28
28
29
29
* 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 ] .
33
36
* Breaking the [ pointer aliasing rules] . ` Box<T> ` , ` &mut T ` and ` &T ` follow
34
37
LLVM’s scoped [ noalias] model, except if the ` &T ` contains an
35
38
[ ` UnsafeCell<U> ` ] . References and boxes must not be [ dangling] while they are
@@ -68,7 +71,7 @@ Please read the [Rustonomicon] before writing unsafe code.
68
71
* A ` ! ` (all values are invalid for this type).
69
72
* An integer (` i* ` /` u* ` ), floating point value (` f* ` ), or raw pointer obtained
70
73
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.
72
75
* Invalid metadata in a wide reference, ` Box<T> ` , or raw pointer:
73
76
* ` dyn Trait ` metadata is invalid if it is not a pointer to a vtable for
74
77
` 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"
102
105
103
106
The 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 ` ).
104
107
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
+
105
138
### Dangling pointers
106
139
[ dangling ] : #dangling-pointers
107
140
@@ -128,8 +161,11 @@ must never exceed `isize::MAX`.
128
161
[ Rustonomicon ] : ../nomicon/index.html
129
162
[ `NonNull<T>` ] : ../core/ptr/struct.NonNull.html
130
163
[ `NonZero*` ] : ../core/num/index.html
131
- [ dereference expression ] : expressions/operator-expr.md#the-dereference-operator
132
164
[ place expression context ] : expressions.md#place-expressions-and-value-expressions
133
165
[ rules ] : inline-assembly.md#rules-for-inline-assembly
134
166
[ points to ] : #pointed-to-bytes
135
167
[ 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