|
23 | 23 | </div>
|
24 | 24 |
|
25 | 25 | * Data races.
|
26 |
| -* Accessing (loading from or storing to) a place that is [dangling] or unaligned. |
| 26 | +* Accessing (loading from or storing to) a place that is [dangling] or [based on |
| 27 | + a misaligned pointer]. |
27 | 28 | * Performing a place projection that violates the requirements of [in-bounds
|
28 | 29 | pointer arithmetic][offset]. A place projection is a [field
|
29 | 30 | expression][project-field], a [tuple index expression][project-tuple], or an
|
|
66 | 67 | * A `!` (all values are invalid for this type).
|
67 | 68 | * An integer (`i*`/`u*`), floating point value (`f*`), or raw pointer obtained
|
68 | 69 | from [uninitialized memory][undef], or uninitialized memory in a `str`.
|
69 |
| - * A reference or `Box<T>` that is [dangling], unaligned, or points to an invalid value. |
| 70 | + * A reference or `Box<T>` that is [dangling], misaligned, or points to an invalid value. |
70 | 71 | * Invalid metadata in a wide reference, `Box<T>`, or raw pointer:
|
71 | 72 | * `dyn Trait` metadata is invalid if it is not a pointer to a vtable for
|
72 | 73 | `Trait` that matches the actual dynamic trait the pointer or reference points to.
|
@@ -100,6 +101,36 @@ reading uninitialized memory is permitted are inside `union`s and in "padding"
|
100 | 101 |
|
101 | 102 | 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`).
|
102 | 103 |
|
| 104 | +### Places based on misaligned pointers |
| 105 | +[based on a misaligned pointer]: #places-based-on-misaligned-pointers |
| 106 | + |
| 107 | +A place is said to be "based on a misaligned pointer" if the last `*` projection |
| 108 | +during place computation was performed on a pointer that was not aligned for its |
| 109 | +type. (If there is no `*` projection in the place expression, then this is |
| 110 | +accessing the field of a local and rustc will guarantee proper alignment. If |
| 111 | +there are multiple `*` projection, then each of them incurs a load of the |
| 112 | +pointer-to-be-dereferenced itself from memory, and each of these loads is |
| 113 | +subject to the alignment constraint. Note that some `*` projections can be |
| 114 | +omitted in surface Rust syntax due to automatic dereferencing; we are |
| 115 | +considering the fully expanded place expression here.) |
| 116 | + |
| 117 | +For instance, if `ptr` has type `*const S` where `S` has an alignment of 8, then |
| 118 | +`ptr` must be 8-aligned or else `(*ptr).f` is "based on an misaligned pointer". |
| 119 | +This is true even if the type of the field `f` is `u8` (i.e., a type with |
| 120 | +alignment 1). In other words, the alignment requirement derives from the type of |
| 121 | +the pointer that was dereferenced, *not* the type of the field that is being |
| 122 | +accessed. |
| 123 | + |
| 124 | +Note that a place based on a misaligned pointer only leads to Undefined Behavior |
| 125 | +when it is loaded from or stored to. `addr_of!`/`addr_of_mut!` on such a place |
| 126 | +is allowed. `&`/`&mut` on a place requires the alignment of the field type (or |
| 127 | +else the program would be "producing an invalid value"), which generally is a |
| 128 | +less restrictive requirement than being based on an aligned pointer. Taking a |
| 129 | +reference will lead to a compiler error in cases where the field type might be |
| 130 | +more aligned than the type that contains it, i.e., `repr(packed)`. This means |
| 131 | +that being based on an aligned pointer is always sufficient to ensure that the |
| 132 | +new reference is aligned, but it is not always necessary. |
| 133 | + |
103 | 134 | ### Dangling pointers
|
104 | 135 | [dangling]: #dangling-pointers
|
105 | 136 |
|
|
0 commit comments