Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: rust-lang/reference
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 5262e1c3b43a2c489df8f6717683a44c7a2260fd
Choose a base ref
...
head repository: rust-lang/reference
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 142b2ed77d33f37a9973772bd95e6144ed9dce43
Choose a head ref
  • 5 commits
  • 2 files changed
  • 3 contributors

Commits on Sep 26, 2023

  1. docs: Fix links to ECMA standards in attributes.md

    The links to the ECMA-334 and ECMA-335 were broken, I have updated those to working links.
    ghoseb authored Sep 26, 2023
    Copy the full SHA
    9d351cc View commit details
  2. Merge pull request #1408 from ghoseb/patch-1

    docs: Fix links to ECMA standards in `attributes.md`
    ehuss authored Sep 26, 2023

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    06db8fa View commit details

Commits on Oct 7, 2023

  1. Unverified

    This user has not yet uploaded their public signing key.
    Copy the full SHA
    b29823c View commit details
  2. explain place alignment

    RalfJung committed Oct 7, 2023
    Copy the full SHA
    051d5d7 View commit details
  3. Merge pull request #1387 from RalfJung/raw-ptr-ub

    replace 'UB on raw ptr deref' with UB on place projection/access
    ehuss authored Oct 7, 2023
    Copy the full SHA
    142b2ed View commit details
Showing with 43 additions and 7 deletions.
  1. +2 −2 src/attributes.md
  2. +41 −5 src/behavior-considered-undefined.md
4 changes: 2 additions & 2 deletions src/attributes.md
Original file line number Diff line number Diff line change
@@ -275,8 +275,8 @@ The following is an index of all built-in attributes.
- [`debugger_visualizer`] — Embeds a file that specifies debugger output for a type.

[Doc comments]: comments.md#doc-comments
[ECMA-334]: https://www.ecma-international.org/publications/standards/Ecma-334.htm
[ECMA-335]: https://www.ecma-international.org/publications/standards/Ecma-335.htm
[ECMA-334]: https://www.ecma-international.org/publications-and-standards/standards/ecma-334/
[ECMA-335]: https://www.ecma-international.org/publications-and-standards/standards/ecma-335/
[Expression Attributes]: expressions.md#expression-attributes
[IDENTIFIER]: identifiers.md
[RAW_STRING_LITERAL]: tokens.md#raw-string-literals
46 changes: 41 additions & 5 deletions src/behavior-considered-undefined.md
Original file line number Diff line number Diff line change
@@ -27,9 +27,12 @@ Please read the [Rustonomicon] before writing unsafe code.
</div>

* Data races.
* Evaluating a [dereference expression] (`*expr`) on a raw pointer that is
[dangling] or unaligned, even in [place expression context]
(e.g. `addr_of!(*expr)`).
* Accessing (loading from or storing to) a place that is [dangling] or [based on
a misaligned pointer].
* Performing a place projection that violates the requirements of [in-bounds
pointer arithmetic][offset]. A place projection is a [field
expression][project-field], a [tuple index expression][project-tuple], or an
[array/slice index expression][project-slice].
* Breaking the [pointer aliasing rules]. `Box<T>`, `&mut T` and `&T` follow
LLVM’s scoped [noalias] model, except if the `&T` contains an
[`UnsafeCell<U>`]. References and boxes must not be [dangling] while they are
@@ -68,7 +71,7 @@ Please read the [Rustonomicon] before writing unsafe code.
* A `!` (all values are invalid for this type).
* An integer (`i*`/`u*`), floating point value (`f*`), or raw pointer obtained
from [uninitialized memory][undef], or uninitialized memory in a `str`.
* A reference or `Box<T>` that is [dangling], unaligned, or points to an invalid value.
* A reference or `Box<T>` that is [dangling], misaligned, or points to an invalid value.
* Invalid metadata in a wide reference, `Box<T>`, or raw pointer:
* `dyn Trait` metadata is invalid if it is not a pointer to a vtable for
`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"

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`).

### Places based on misaligned pointers
[based on a misaligned pointer]: #places-based-on-misaligned-pointers

A place is said to be "based on a misaligned pointer" if the last `*` projection
during place computation was performed on a pointer that was not aligned for its
type. (If there is no `*` projection in the place expression, then this is
accessing the field of a local and rustc will guarantee proper alignment. If
there are multiple `*` projection, then each of them incurs a load of the
pointer-to-be-dereferenced itself from memory, and each of these loads is
subject to the alignment constraint. Note that some `*` projections can be
omitted in surface Rust syntax due to automatic dereferencing; we are
considering the fully expanded place expression here.)

For instance, if `ptr` has type `*const S` where `S` has an alignment of 8, then
`ptr` must be 8-aligned or else `(*ptr).f` is "based on an misaligned pointer".
This is true even if the type of the field `f` is `u8` (i.e., a type with
alignment 1). In other words, the alignment requirement derives from the type of
the pointer that was dereferenced, *not* the type of the field that is being
accessed.

Note that a place based on a misaligned pointer only leads to Undefined Behavior
when it is loaded from or stored to. `addr_of!`/`addr_of_mut!` on such a place
is allowed. `&`/`&mut` on a place requires the alignment of the field type (or
else the program would be "producing an invalid value"), which generally is a
less restrictive requirement than being based on an aligned pointer. Taking a
reference will lead to a compiler error in cases where the field type might be
more aligned than the type that contains it, i.e., `repr(packed)`. This means
that being based on an aligned pointer is always sufficient to ensure that the
new reference is aligned, but it is not always necessary.

### Dangling pointers
[dangling]: #dangling-pointers

@@ -128,8 +161,11 @@ must never exceed `isize::MAX`.
[Rustonomicon]: ../nomicon/index.html
[`NonNull<T>`]: ../core/ptr/struct.NonNull.html
[`NonZero*`]: ../core/num/index.html
[dereference expression]: expressions/operator-expr.md#the-dereference-operator
[place expression context]: expressions.md#place-expressions-and-value-expressions
[rules]: inline-assembly.md#rules-for-inline-assembly
[points to]: #pointed-to-bytes
[pointed to]: #pointed-to-bytes
[offset]: ../std/primitive.pointer.html#method.offset
[project-field]: expressions/field-expr.md
[project-tuple]: expressions/tuple-expr.md#tuple-indexing-expressions
[project-slice]: expressions/array-expr.md#array-and-slice-indexing-expressions