Skip to content

Commit 50c5de9

Browse files
authored
Merge pull request #2091 from RalfJung/const-eval-provenance-ub
UB: update the extra clause for provenance UB during const evaluation
2 parents 25f0e6e + f30a5f5 commit 50c5de9

File tree

1 file changed

+31
-8
lines changed

1 file changed

+31
-8
lines changed

src/behavior-considered-undefined.md

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,6 @@ r[undefined.asm]
7676
* Incorrect use of inline assembly. For more details, refer to the [rules] to
7777
follow when writing code that uses inline assembly.
7878

79-
r[undefined.const-transmute-ptr2int]
80-
* **In [const context](const_eval.md#const-context)**: transmuting or otherwise
81-
reinterpreting a pointer (reference, raw pointer, or function pointer) into
82-
some allocation as a non-pointer type (such as integers).
83-
'Reinterpreting' refers to loading the pointer value at integer type without a
84-
cast, e.g. by doing raw pointer casts or using a union.
85-
8679
r[undefined.runtime]
8780
* Violating assumptions of the Rust runtime. Most assumptions of the Rust runtime are currently not explicitly documented.
8881
* For assumptions specifically related to unwinding, see the [panic documentation][unwinding-ffi].
@@ -119,7 +112,7 @@ the pointer that was dereferenced, *not* the type of the field that is being
119112
accessed.
120113

121114
r[undefined.misaligned.load-store]
122-
Note that a place based on a misaligned pointer only leads to Undefined Behavior
115+
Note that a place based on a misaligned pointer only leads to undefined behavior
123116
when it is loaded from or stored to.
124117

125118
r[undefined.misaligned.raw]
@@ -221,6 +214,35 @@ r[undefined.validity.valid-range]
221214
> [!NOTE]
222215
> `rustc` achieves this with the unstable `rustc_layout_scalar_valid_range_*` attributes.
223216
217+
r[undefined.validity.const-provenance]
218+
* **In [const contexts]**: In addition to what is described above, further provenance-related requirements apply during const evaluation. Any value that holds pure integer data (the `i*`/`u*`/`f*` types as well as `bool` and `char`, enum discriminants, and slice metadata) must not carry any provenance. Any value that holds pointer data (references, raw pointers, function pointers, and `dyn Trait` metadata) must either carry no provenance, or all bytes must be fragments of the same original pointer value in the correct order.
219+
220+
This implies that transmuting or otherwise reinterpreting a pointer (reference, raw pointer, or function pointer) into a non-pointer type (such as integers) is undefined behavior if the pointer had provenance.
221+
222+
> [!EXAMPLE]
223+
> All of the following are UB:
224+
>
225+
> ```rust,compile_fail
226+
> # use core::mem::MaybeUninit;
227+
> # use core::ptr;
228+
> // We cannot reinterpret a pointer with provenance as an integer,
229+
> // as then the bytes of the integer will have provenance.
230+
> const _: usize = {
231+
> let ptr = &0;
232+
> unsafe { (&raw const ptr as *const usize).read() }
233+
> };
234+
>
235+
> // We cannot rearrange the bytes of a pointer with provenance and
236+
> // then interpret them as a reference, as then a value holding
237+
> // pointer data will have pointer fragments in the wrong order.
238+
> const _: &i32 = {
239+
> let mut ptr = &0;
240+
> let ptr_bytes = &raw mut ptr as *mut MaybeUninit::<u8>;
241+
> unsafe { ptr::swap(ptr_bytes.add(1), ptr_bytes.add(2)) };
242+
> ptr
243+
> };
244+
> ```
245+
224246
r[undefined.validity.undef]
225247
**Note:** Uninitialized memory is also implicitly invalid for any type that has
226248
a restricted set of valid values. In other words, the only cases in which
@@ -230,6 +252,7 @@ reading uninitialized memory is permitted are inside `union`s and in "padding"
230252
[`bool`]: types/boolean.md
231253
[`const`]: items/constant-items.md
232254
[abi]: items/external-blocks.md#abi
255+
[const contexts]: const-eval.const-context
233256
[`target_feature`]: attributes/codegen.md#the-target_feature-attribute
234257
[`UnsafeCell<U>`]: std::cell::UnsafeCell
235258
[Rustonomicon]: ../nomicon/index.html

0 commit comments

Comments
 (0)