Skip to content

Commit

Permalink
Clarify UB around immutability & mutation
Browse files Browse the repository at this point in the history
I personally found this description of UB confusing, since the use of
"reached" suggests that UB only happens for read bytes, and the
definition of immutability is not given, allowing for multiple
interpretations: does the "data" have to be immutable from the first
read? From the creation of the reference? Between reads from the
immutable accessor, but not otherwise? etc.

This clarifies the actual UB conditions, based on this Zulip
interaction:
https://rust-lang.zulipchat.com/#narrow/stream/136281-t-opsem/topic/What.20exactly.20are.20.22immutable.22.20and.20.22reached.22.20in.20shared.20ref.20UB.3F
and this reference discussion:
#1227
in two ways:
  * The definition of "data" is clarified to be stated in terms of
    bytes, in a way that should avoid ambiguity about which bytes are
    considered. Based on the GH issue, this clarification should also
    allow for use of a `*mut` pointer through a shared reference, which
    is not in itself UB. Based on the Zulip issue, the definition
    includes padding bytes, which may be surprising.
  * The definition of immutability & mutation for a set of bytes is
    clarified to mean forbidding *all* non-0-byte writes.
  • Loading branch information
Isaac van Bakel committed Jul 21, 2023
1 parent e94fb3d commit 3514a23
Showing 1 changed file with 6 additions and 3 deletions.
9 changes: 6 additions & 3 deletions src/behavior-considered-undefined.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,12 @@ code.
All this also applies when values of these
types are passed in a (nested) field of a compound type, but not behind
pointer indirections.
* Mutating immutable data. All data inside a [`const`] item is immutable. Moreover, all
data reached through a shared reference or data owned by an immutable binding
is immutable, unless that data is contained within an [`UnsafeCell<U>`].
* Mutating immutable data. All bytes inside a [`const`] item are immutable.
Moreover, the bytes of a value pointed to by a shared reference, or bytes owned by an immutable binding are immutable, unless those bytes are part of an [`UnsafeCell<U>`].
Immutability also affects bytes which are not reachable from safe code, such as padding; it also affects uninitialized bytes.

A mutation is any write of more than 0 bytes which overlaps with any of the relevant bytes.
Writes which do not modify the byte contents (i.e. writes of a byte's value to that byte) are still mutations.
* Invoking undefined behavior via compiler intrinsics.
* Executing code compiled with platform features that the current platform
does not support (see [`target_feature`]), *except* if the platform explicitly documents this to be safe.
Expand Down

0 comments on commit 3514a23

Please sign in to comment.