]>
Commit | Line | Data |
---|---|---|
8bb4bdeb XL |
1 | ## Behavior considered undefined |
2 | ||
416331ca XL |
3 | Rust code is incorrect if it exhibits any of the behaviors in the following |
4 | list. This includes code within `unsafe` blocks and `unsafe` functions. | |
5 | `unsafe` only means that avoiding undefined behavior is on the programmer; it | |
6 | does not change anything about the fact that Rust programs must never cause | |
7 | undefined behavior. | |
8 | ||
9 | It is the programmer's responsibility when writing `unsafe` code to ensure that | |
10 | any safe code interacting with the `unsafe` code cannot trigger these | |
11 | behaviors. `unsafe` code that satisfies this property for any safe client is | |
12 | called *sound*; if `unsafe` code can be misused by safe code to exhibit | |
13 | undefined behavior, it is *unsound*. | |
8bb4bdeb | 14 | |
b7449926 XL |
15 | <div class="warning"> |
16 | ||
17 | ***Warning:*** The following list is not exhaustive. There is no formal model of | |
18 | Rust's semantics for what is and is not allowed in unsafe code, so there may be | |
19 | more behavior considered unsafe. The following list is just what we know for | |
20 | sure is undefined behavior. Please read the [Rustonomicon] before writing unsafe | |
21 | code. | |
22 | ||
23 | </div> | |
24 | ||
ea8adc8c | 25 | * Data races. |
cdc7bbd5 XL |
26 | * Evaluating a [dereference expression] (`*expr`) on a raw pointer that is |
27 | [dangling] or unaligned, even in [place expression context] | |
28 | (e.g. `addr_of!(&*expr)`). | |
6522a427 EL |
29 | * Breaking the [pointer aliasing rules]. `Box<T>`, `&mut T` and `&T` follow |
30 | LLVM’s scoped [noalias] model, except if the `&T` contains an | |
31 | [`UnsafeCell<U>`]. References and boxes must not be [dangling] while they are | |
32 | live. The exact liveness duration is not specified, but some bounds exist: | |
33 | * For references, the liveness duration is upper-bounded by the syntactic | |
34 | lifetime assigned by the borrow checker; it cannot be live any *longer* than | |
35 | that lifetime. | |
36 | * Each time a reference or box is passed to or returned from a function, it is | |
37 | considered live. | |
38 | * When a reference (but not a `Box`!) is passed to a function, it is live at | |
39 | least as long as that function call, again except if the `&T` contains an | |
40 | [`UnsafeCell<U>`]. | |
41 | ||
42 | All this also applies when values of these | |
43 | types are passed in a (nested) field of a compound type, but not behind | |
44 | pointer indirections. | |
e1599b0c XL |
45 | * Mutating immutable data. All data inside a [`const`] item is immutable. Moreover, all |
46 | data reached through a shared reference or data owned by an immutable binding | |
47 | is immutable, unless that data is contained within an [`UnsafeCell<U>`]. | |
48 | * Invoking undefined behavior via compiler intrinsics. | |
49 | * Executing code compiled with platform features that the current platform | |
5e7ed085 | 50 | does not support (see [`target_feature`]), *except* if the platform explicitly documents this to be safe. |
e1599b0c XL |
51 | * Calling a function with the wrong call ABI or unwinding from a function with the wrong unwind ABI. |
52 | * Producing an invalid value, even in private fields and locals. "Producing" a | |
53 | value happens any time a value is assigned to or read from a place, passed to | |
54 | a function/primitive operation or returned from a function/primitive | |
55 | operation. | |
56 | The following values are invalid (at their respective type): | |
6a06907d | 57 | * A value other than `false` (`0`) or `true` (`1`) in a [`bool`]. |
ea8adc8c | 58 | * A discriminant in an `enum` not included in the type definition. |
e1599b0c | 59 | * A null `fn` pointer. |
ea8adc8c | 60 | * A value in a `char` which is a surrogate or above `char::MAX`. |
e1599b0c XL |
61 | * A `!` (all values are invalid for this type). |
62 | * An integer (`i*`/`u*`), floating point value (`f*`), or raw pointer obtained | |
f9f354fc | 63 | from [uninitialized memory][undef], or uninitialized memory in a `str`. |
cdc7bbd5 | 64 | * A reference or `Box<T>` that is [dangling], unaligned, or points to an invalid value. |
e1599b0c XL |
65 | * Invalid metadata in a wide reference, `Box<T>`, or raw pointer: |
66 | * `dyn Trait` metadata is invalid if it is not a pointer to a vtable for | |
67 | `Trait` that matches the actual dynamic trait the pointer or reference points to. | |
74b04a01 | 68 | * Slice metadata is invalid if the length is not a valid `usize` |
e1599b0c | 69 | (i.e., it must not be read from uninitialized memory). |
e1599b0c XL |
70 | * Invalid values for a type with a custom definition of invalid values. |
71 | In the standard library, this affects [`NonNull<T>`] and [`NonZero*`]. | |
72 | ||
73 | > **Note**: `rustc` achieves this with the unstable | |
74 | > `rustc_layout_scalar_valid_range_*` attributes. | |
a2a8927a XL |
75 | * Incorrect use of inline assembly. For more details, refer to the [rules] to |
76 | follow when writing code that uses inline assembly. | |
e1599b0c | 77 | |
1b1a35ee XL |
78 | **Note:** Uninitialized memory is also implicitly invalid for any type that has |
79 | a restricted set of valid values. In other words, the only cases in which | |
80 | reading uninitialized memory is permitted are inside `union`s and in "padding" | |
81 | (the gaps between the fields/elements of a type). | |
82 | ||
cdc7bbd5 XL |
83 | > **Note**: Undefined behavior affects the entire program. For example, calling |
84 | > a function in C that exhibits undefined behavior of C means your entire | |
85 | > program contains undefined behaviour that can also affect the Rust code. And | |
86 | > vice versa, undefined behavior in Rust can cause adverse affects on code | |
87 | > executed by any FFI calls to other languages. | |
88 | ||
89 | ### Dangling pointers | |
90 | [dangling]: #dangling-pointers | |
91 | ||
e1599b0c | 92 | A reference/pointer is "dangling" if it is null or not all of the bytes it |
064997fb | 93 | points to are part of the same live allocation (so in particular they all have to be |
e1599b0c | 94 | part of *some* allocation). The span of bytes it points to is determined by the |
064997fb FG |
95 | pointer value and the size of the pointee type (using `size_of_val`). |
96 | ||
97 | If the size is 0, then the pointer must either point inside of a live allocation | |
98 | (including pointing just after the last byte of the allocation), or it must be | |
99 | directly constructed from a non-zero integer literal. | |
100 | ||
101 | Note that dynamically sized types (such as slices and strings) point to their | |
102 | entire range, so it is important that the length metadata is never too large. In | |
103 | particular, the dynamic size of a Rust value (as determined by `size_of_val`) | |
104 | must never exceed `isize::MAX`. | |
532ac7d7 | 105 | |
6a06907d XL |
106 | [`bool`]: types/boolean.md |
107 | [`const`]: items/constant-items.md | |
8bb4bdeb | 108 | [noalias]: http://llvm.org/docs/LangRef.html#noalias |
ea8adc8c XL |
109 | [pointer aliasing rules]: http://llvm.org/docs/LangRef.html#pointer-aliasing-rules |
110 | [undef]: http://llvm.org/docs/LangRef.html#undefined-values | |
416331ca | 111 | [`target_feature`]: attributes/codegen.md#the-target_feature-attribute |
532ac7d7 | 112 | [`UnsafeCell<U>`]: ../std/cell/struct.UnsafeCell.html |
b7449926 | 113 | [Rustonomicon]: ../nomicon/index.html |
e1599b0c XL |
114 | [`NonNull<T>`]: ../core/ptr/struct.NonNull.html |
115 | [`NonZero*`]: ../core/num/index.html | |
cdc7bbd5 XL |
116 | [dereference expression]: expressions/operator-expr.md#the-dereference-operator |
117 | [place expression context]: expressions.md#place-expressions-and-value-expressions | |
a2a8927a | 118 | [rules]: inline-assembly.md#rules-for-inline-assembly |