From c728977c23b2abdcf090ac9870ab662f4e4e61ef Mon Sep 17 00:00:00 2001 From: akriso Date: Mon, 18 Aug 2025 16:27:24 +0200 Subject: [PATCH 1/2] Add guideline forbidding undefined behavior --- src/coding-guidelines/unsafety.rst | 51 ++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/coding-guidelines/unsafety.rst b/src/coding-guidelines/unsafety.rst index e8e1319..d16f34d 100644 --- a/src/coding-guidelines/unsafety.rst +++ b/src/coding-guidelines/unsafety.rst @@ -5,3 +5,54 @@ Unsafety ======== + +.. guideline:: Undefined behavior shall not occur during the execution of a program + :id: gui_n4sX2E4G2qoX + :category: required + :status: draft + :release: - + :fls: fls_ovn9czwnwxue + :decidability: undecidable + :scope: system + :tags: undefined-behavior + + This rule addresses all instances of undefined behavior not already covered by other guidelines. + + .. rationale:: + :id: rat_xYF9mDPQRStx + :status: draft + + Once an execution encounters undefined behavior it is impossible to reason about it anymore. + Instances of undefined behavior can manifest in any kind of undesired behavior like + crashes or silent memory corruption. + + .. non_compliant_example:: + :id: non_compl_ex_bkYi0Sb97r3N + :status: draft + + Explanation of code example. + + The only allowed representation of ``bool`` is either 0 or 1. + Therefore, transmuting ``3_u8`` to ``bool`` violates its validity invariant and is undefined behavior. + + .. code-block:: rust + + fn example_function() { + unsafe { + std::transmute(3_u8) + } + } + + A necessary condition to read the value behind a pointer is that it points to a live allocation. + This is never the case for the live pointer, therefore reading a null pointer is undefined behavior. + See the safety precondition of :std:`std::ptr::read`. + + .. code-block:: rust + + fn example_function() { + unsafe { + std::ptr::read(std::ptr::null()); + } + } + + From c17f7d7c5e3ea2d26ecf9a8a8a5422608f7ede1d Mon Sep 17 00:00:00 2001 From: akriso Date: Mon, 18 Aug 2025 16:40:18 +0200 Subject: [PATCH 2/2] Add compliant example --- src/coding-guidelines/unsafety.rst | 33 +++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/coding-guidelines/unsafety.rst b/src/coding-guidelines/unsafety.rst index d16f34d..2d02f9b 100644 --- a/src/coding-guidelines/unsafety.rst +++ b/src/coding-guidelines/unsafety.rst @@ -37,14 +37,14 @@ Unsafety .. code-block:: rust - fn example_function() { + fn example_function() -> bool { unsafe { std::transmute(3_u8) } } - A necessary condition to read the value behind a pointer is that it points to a live allocation. - This is never the case for the live pointer, therefore reading a null pointer is undefined behavior. + A necessary condition to read the value behind a pointer is that it points to a valid allocation. + This is never the case for a null pointer, therefore reading it is undefined behavior. See the safety precondition of :std:`std::ptr::read`. .. code-block:: rust @@ -55,4 +55,31 @@ Unsafety } } + .. compliant_example:: + :id: compl_ex_mt8h0T3BtONt + :status: draft + + Since ``0_u8`` is defined to represent the ``false`` value of bool, this example is free of + undefined behavior. + + .. code-block:: rust + + fn example_function() -> bool { + unsafe { + std::transmute(0_u8); + } + } + + ``ptr`` points to a valid, aligned and properly initialized allocation. + Therefore, it satisfies all safety preconditions of :std:`std::ptr::read` and can be read + without undefined behavior. + + .. code-block:: rust + + fn example_function() { + let ptr = Box::new(42).into_raw(); + unsafe { + std::ptr::read(ptr); + } + }