From 70ae39719922afabf74ae840f13cc34881be9268 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 5 Mar 2025 17:38:43 +0100 Subject: [PATCH 1/3] do not reference LLVM in our definition of UB --- src/behavior-considered-undefined.md | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index a11e67aec..a3b663bb2 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -43,10 +43,11 @@ r[undefined.place-projection] [array/slice index expression][project-slice]. r[undefined.alias] -* Breaking the [pointer aliasing rules]. `Box`, `&mut T` and `&T` follow - LLVM’s scoped [noalias] model, except if the `&T` contains an - [`UnsafeCell`]. References and boxes must not be [dangling] while they are - live. The exact liveness duration is not specified, but some bounds exist: +* Breaking the pointer aliasing rules. The exact aliasing rules are not determined yet, but here is a rough sketch of what the requirements look like: + `&T` must point to memory that is not mutated while they are live (except for data inside an [`UnsafeCell`]), + and `&mut T` must point to memory that is not read or written by any pointer not derived from the reference and that no other reference points to while they are live. + `Box` is treated similar to `&'static mut T` for the purpose of these rules. + The exact liveness duration is not specified, but some bounds exist: * For references, the liveness duration is upper-bounded by the syntactic lifetime assigned by the borrow checker; it cannot be live any *longer* than that lifetime. @@ -56,9 +57,7 @@ r[undefined.alias] least as long as that function call, again except if the `&T` contains an [`UnsafeCell`]. - All this also applies when values of these - types are passed in a (nested) field of a compound type, but not behind - pointer indirections. + All this also applies when values of these types are passed in a (nested) field of a compound type, but not behind pointer indirections. r[undefined.immutable] * Mutating immutable bytes. @@ -201,7 +200,7 @@ r[undefined.validity.never] r[undefined.validity.scalar] * An integer (`i*`/`u*`), floating point value (`f*`), or raw pointer must be - initialized, i.e., must not be obtained from [uninitialized memory][undef]. + initialized, i.e., must not be obtained from uninitialized memory. r[undefined.validity.str] * A `str` value is treated like `[u8]`, i.e. it must be initialized. @@ -248,10 +247,7 @@ reading uninitialized memory is permitted are inside `union`s and in "padding" [`bool`]: types/boolean.md [`const`]: items/constant-items.md -[noalias]: http://llvm.org/docs/LangRef.html#noalias -[pointer aliasing rules]: http://llvm.org/docs/LangRef.html#pointer-aliasing-rules [abi]: items/external-blocks.md#abi -[undef]: http://llvm.org/docs/LangRef.html#undefined-values [`target_feature`]: attributes/codegen.md#the-target_feature-attribute [`UnsafeCell`]: std::cell::UnsafeCell [Rustonomicon]: ../nomicon/index.html From cfd33b02fb878a74882894e3caf6c3eb1b339074 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 10 Mar 2025 13:52:03 +0100 Subject: [PATCH 2/3] clarify liveness rules --- src/behavior-considered-undefined.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index a3b663bb2..c7ce6425c 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -49,13 +49,10 @@ r[undefined.alias] `Box` is treated similar to `&'static mut T` for the purpose of these rules. The exact liveness duration is not specified, but some bounds exist: * For references, the liveness duration is upper-bounded by the syntactic - lifetime assigned by the borrow checker; it cannot be live any *longer* than - that lifetime. - * Each time a reference or box is passed to or returned from a function, it is - considered live. - * When a reference (but not a `Box`!) is passed to a function, it is live at - least as long as that function call, again except if the `&T` contains an - [`UnsafeCell`]. + lifetime assigned by the borrow checker; it cannot be live any *longer* than that lifetime. + * Each time a reference or box is dereferenced or reborrowed, it is considered live. + * Each time a reference or box is passed to or returned from a function, it is considered live. + * When a reference (but not a `Box`!) is passed to a function, it is live at least as long as that function call, again except if the `&T` contains an [`UnsafeCell`]. All this also applies when values of these types are passed in a (nested) field of a compound type, but not behind pointer indirections. From 80e42688fea7f513368d835887c4c604ac7a3781 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 27 Mar 2025 18:16:40 +0100 Subject: [PATCH 3/3] finesse wording --- src/behavior-considered-undefined.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index c7ce6425c..abd814e02 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -43,7 +43,7 @@ r[undefined.place-projection] [array/slice index expression][project-slice]. r[undefined.alias] -* Breaking the pointer aliasing rules. The exact aliasing rules are not determined yet, but here is a rough sketch of what the requirements look like: +* Breaking the pointer aliasing rules. The exact aliasing rules are not determined yet, but here is an outline of the general principles: `&T` must point to memory that is not mutated while they are live (except for data inside an [`UnsafeCell`]), and `&mut T` must point to memory that is not read or written by any pointer not derived from the reference and that no other reference points to while they are live. `Box` is treated similar to `&'static mut T` for the purpose of these rules.