Skip to content

Commit 9fa09f3

Browse files
authored
Merge pull request #659 from RalfJung/ub
update UB
2 parents 090c015 + 6c9a399 commit 9fa09f3

File tree

1 file changed

+42
-24
lines changed

1 file changed

+42
-24
lines changed

src/behavior-considered-undefined.md

+42-24
Original file line numberDiff line numberDiff line change
@@ -23,44 +23,62 @@ code.
2323
</div>
2424

2525
* Data races.
26-
* Dereferencing a null or dangling raw pointer.
27-
* Unaligned pointer reading and writing outside of [`read_unaligned`]
28-
and [`write_unaligned`].
29-
* Reads of [undef] \(uninitialized) memory.
30-
* Breaking the [pointer aliasing rules] on accesses through raw pointers;
31-
a subset of the rules used by C.
32-
* `&mut T` and `&T` follow LLVM’s scoped [noalias] model, except if the `&T`
33-
contains an [`UnsafeCell<U>`].
34-
* Mutating non-mutable data &mdash; that is, data reached through a shared
35-
reference or data owned by a `let` binding), unless that data is contained
36-
within an [`UnsafeCell<U>`].
37-
* Invoking undefined behavior via compiler intrinsics:
38-
* Indexing outside of the bounds of an object with [`offset`] with
39-
the exception of one byte past the end of the object.
40-
* Using [`std::ptr::copy_nonoverlapping_memory`], a.k.a. the `memcpy32`and
41-
`memcpy64` intrinsics, on overlapping buffers.
42-
* Invalid values in primitive types, even in private fields and locals:
43-
* Dangling or null references and boxes.
26+
* Dereferencing (using the `*` operator on) a dangling or unaligned raw pointer.
27+
* Breaking the [pointer aliasing rules]. `&mut T` and `&T` follow LLVM’s scoped
28+
[noalias] model, except if the `&T` contains an [`UnsafeCell<U>`].
29+
* Mutating immutable data. All data inside a [`const`] item is immutable. Moreover, all
30+
data reached through a shared reference or data owned by an immutable binding
31+
is immutable, unless that data is contained within an [`UnsafeCell<U>`].
32+
* Invoking undefined behavior via compiler intrinsics.
33+
* Executing code compiled with platform features that the current platform
34+
does not support (see [`target_feature`]).
35+
* Calling a function with the wrong call ABI or wrong unwind ABI.
36+
* Producing an invalid value, even in private fields and locals. "Producing" a
37+
value happens any time a value is assigned to or read from a place, passed to
38+
a function/primitive operation or returned from a function/primitive
39+
operation.
40+
The following values are invalid (at their respective type):
4441
* A value other than `false` (`0`) or `true` (`1`) in a `bool`.
4542
* A discriminant in an `enum` not included in the type definition.
43+
* A null `fn` pointer.
4644
* A value in a `char` which is a surrogate or above `char::MAX`.
45+
* A `!` (all values are invalid for this type).
46+
* An integer (`i*`/`u*`), floating point value (`f*`), or raw pointer obtained
47+
from [uninitialized memory][undef].
48+
* A reference or `Box<T>` that is dangling, unaligned, or points to an invalid value.
49+
* Invalid metadata in a wide reference, `Box<T>`, or raw pointer:
50+
* `dyn Trait` metadata is invalid if it is not a pointer to a vtable for
51+
`Trait` that matches the actual dynamic trait the pointer or reference points to.
52+
* Slice metadata is invalid if if the length is not a valid `usize`
53+
(i.e., it must not be read from uninitialized memory).
4754
* Non-UTF-8 byte sequences in a `str`.
48-
* Executing code compiled with platform features that the current platform
49-
does not support (see [`target_feature`]).
55+
* Invalid values for a type with a custom definition of invalid values.
56+
In the standard library, this affects [`NonNull<T>`] and [`NonZero*`].
57+
58+
> **Note**: `rustc` achieves this with the unstable
59+
> `rustc_layout_scalar_valid_range_*` attributes.
60+
61+
A reference/pointer is "dangling" if it is null or not all of the bytes it
62+
points to are part of the same allocation (so in particular they all have to be
63+
part of *some* allocation). The span of bytes it points to is determined by the
64+
pointer value and the size of the pointee type. As a consequence, if the span is
65+
empty, "dangling" is the same as "non-null". Note that slices point to their
66+
entire range, so it is important that the length metadata is never too
67+
large. In particular, allocations and therefore slices cannot be bigger than
68+
`isize::MAX` bytes.
5069

5170
> **Note**: Undefined behavior affects the entire program. For example, calling
5271
> a function in C that exhibits undefined behavior of C means your entire
5372
> program contains undefined behaviour that can also affect the Rust code. And
5473
> vice versa, undefined behavior in Rust can cause adverse affects on code
5574
> executed by any FFI calls to other languages.
5675
76+
[`const`]: items/constant-items.html
5777
[noalias]: http://llvm.org/docs/LangRef.html#noalias
5878
[pointer aliasing rules]: http://llvm.org/docs/LangRef.html#pointer-aliasing-rules
5979
[undef]: http://llvm.org/docs/LangRef.html#undefined-values
60-
[`offset`]: ../std/primitive.pointer.html#method.offset
61-
[`std::ptr::copy_nonoverlapping_memory`]: ../std/ptr/fn.copy_nonoverlapping.html
6280
[`target_feature`]: attributes/codegen.md#the-target_feature-attribute
6381
[`UnsafeCell<U>`]: ../std/cell/struct.UnsafeCell.html
64-
[`read_unaligned`]: ../std/ptr/fn.read_unaligned.html
65-
[`write_unaligned`]: ../std/ptr/fn.write_unaligned.html
6682
[Rustonomicon]: ../nomicon/index.html
83+
[`NonNull<T>`]: ../core/ptr/struct.NonNull.html
84+
[`NonZero*`]: ../core/num/index.html

0 commit comments

Comments
 (0)