diff options
| author | Matthias Krüger <476013+matthiaskrgr@users.noreply.github.com> | 2025-07-20 08:56:05 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-20 08:56:05 +0200 |
| commit | 6d7d366fd3c1ae6ce722e46d1fecfdf258d02f9d (patch) | |
| tree | 8d13623ca86e733418a5009fe6751f91150f4702 /tests | |
| parent | 6707bf0f59485cf054ac1095725df43220e4be20 (diff) | |
| parent | 8a8717e971dbdc6155506a4332e9ce8ef9151caa (diff) | |
| download | rust-6d7d366fd3c1ae6ce722e46d1fecfdf258d02f9d.tar.gz rust-6d7d366fd3c1ae6ce722e46d1fecfdf258d02f9d.zip | |
Rollup merge of #141260 - LuigiPiucco:volatile-null, r=RalfJung
Allow volatile access to non-Rust memory, including address 0 This PR relaxes the `ub_check` in the `read_volatile`/`write_volatile` pointer operations to allow passing null. This is needed to support processors which hard-code peripheral registers on address 0, like the AVR chip ATtiny1626. LLVM understands this as valid and handles it correctly, as tested in my [PR to add a note about it](https://github.com/llvm/llvm-project/pull/139803/commits/6387c82255c56d3035d249eb54110695e76b8030#diff-81bbb96298c32fa901beb82ab3b97add27a410c01d577c1f8c01000ed2055826) (rustc generates the same LLVM IR as expected there when this PR is applied, and consequently the same AVR assembly). Follow-up and implementation of the discussions in: - https://internals.rust-lang.org/t/pre-rfc-conditionally-supported-volatile-access-to-address-0/12881/7 - https://github.com/Rahix/avr-device/pull/185; - [#t-lang > Adding the possibility of volatile access to address 0](https://rust-lang.zulipchat.com/#narrow/channel/213817-t-lang/topic/Adding.20the.20possibility.20of.20volatile.20access.20to.20address.200/with/513303502) - https://discourse.llvm.org/t/rfc-volatile-access-to-non-dereferenceable-memory-may-be-well-defined/86303 r? ````@RalfJung```` Also fixes https://github.com/rust-lang/unsafe-code-guidelines/issues/29 (about as good as it'll get, null will likely never be a "normal" address in Rust)
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/ui/lint/invalid_null_args.rs | 5 | ||||
| -rw-r--r-- | tests/ui/lint/invalid_null_args.stderr | 58 | ||||
| -rw-r--r-- | tests/ui/precondition-checks/read_volatile.rs | 6 | ||||
| -rw-r--r-- | tests/ui/precondition-checks/write_volatile.rs | 6 |
4 files changed, 18 insertions, 57 deletions
diff --git a/tests/ui/lint/invalid_null_args.rs b/tests/ui/lint/invalid_null_args.rs index f40f06a0d36..ee29d622ad7 100644 --- a/tests/ui/lint/invalid_null_args.rs +++ b/tests/ui/lint/invalid_null_args.rs @@ -58,10 +58,9 @@ unsafe fn null_ptr() { let _a: A = ptr::read_unaligned(ptr::null_mut()); //~^ ERROR calling this function with a null pointer is undefined behavior + // These two should *not* fire the lint. let _a: A = ptr::read_volatile(ptr::null()); - //~^ ERROR calling this function with a null pointer is undefined behavior let _a: A = ptr::read_volatile(ptr::null_mut()); - //~^ ERROR calling this function with a null pointer is undefined behavior let _a: A = ptr::replace(ptr::null_mut(), v); //~^ ERROR calling this function with a null pointer is undefined behavior @@ -82,8 +81,8 @@ unsafe fn null_ptr() { ptr::write_unaligned(ptr::null_mut(), v); //~^ ERROR calling this function with a null pointer is undefined behavior + // This one should *not* fire the lint. ptr::write_volatile(ptr::null_mut(), v); - //~^ ERROR calling this function with a null pointer is undefined behavior ptr::write_bytes::<usize>(ptr::null_mut(), 42, 0); //~^ ERROR calling this function with a null pointer is undefined behavior diff --git a/tests/ui/lint/invalid_null_args.stderr b/tests/ui/lint/invalid_null_args.stderr index 11c6270cfb7..028bd7051dc 100644 --- a/tests/ui/lint/invalid_null_args.stderr +++ b/tests/ui/lint/invalid_null_args.stderr @@ -164,27 +164,7 @@ LL | let _a: A = ptr::read_unaligned(ptr::null_mut()); = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:61:17 - | -LL | let _a: A = ptr::read_volatile(ptr::null()); - | ^^^^^^^^^^^^^^^^^^^-----------^ - | | - | null pointer originates from here - | - = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> - -error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:63:17 - | -LL | let _a: A = ptr::read_volatile(ptr::null_mut()); - | ^^^^^^^^^^^^^^^^^^^---------------^ - | | - | null pointer originates from here - | - = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> - -error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:66:17 + --> $DIR/invalid_null_args.rs:65:17 | LL | let _a: A = ptr::replace(ptr::null_mut(), v); | ^^^^^^^^^^^^^---------------^^^^ @@ -194,7 +174,7 @@ LL | let _a: A = ptr::replace(ptr::null_mut(), v); = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:69:5 + --> $DIR/invalid_null_args.rs:68:5 | LL | ptr::swap::<A>(ptr::null_mut(), &mut v); | ^^^^^^^^^^^^^^^---------------^^^^^^^^^ @@ -204,7 +184,7 @@ LL | ptr::swap::<A>(ptr::null_mut(), &mut v); = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:71:5 + --> $DIR/invalid_null_args.rs:70:5 | LL | ptr::swap::<A>(&mut v, ptr::null_mut()); | ^^^^^^^^^^^^^^^^^^^^^^^---------------^ @@ -214,7 +194,7 @@ LL | ptr::swap::<A>(&mut v, ptr::null_mut()); = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:74:5 + --> $DIR/invalid_null_args.rs:73:5 | LL | ptr::swap_nonoverlapping::<A>(ptr::null_mut(), &mut v, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^^^^^^^^^ @@ -224,7 +204,7 @@ LL | ptr::swap_nonoverlapping::<A>(ptr::null_mut(), &mut v, 0); = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:76:5 + --> $DIR/invalid_null_args.rs:75:5 | LL | ptr::swap_nonoverlapping::<A>(&mut v, ptr::null_mut(), 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^ @@ -234,7 +214,7 @@ LL | ptr::swap_nonoverlapping::<A>(&mut v, ptr::null_mut(), 0); = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:79:5 + --> $DIR/invalid_null_args.rs:78:5 | LL | ptr::write(ptr::null_mut(), v); | ^^^^^^^^^^^---------------^^^^ @@ -244,7 +224,7 @@ LL | ptr::write(ptr::null_mut(), v); = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:82:5 + --> $DIR/invalid_null_args.rs:81:5 | LL | ptr::write_unaligned(ptr::null_mut(), v); | ^^^^^^^^^^^^^^^^^^^^^---------------^^^^ @@ -254,17 +234,7 @@ LL | ptr::write_unaligned(ptr::null_mut(), v); = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:85:5 - | -LL | ptr::write_volatile(ptr::null_mut(), v); - | ^^^^^^^^^^^^^^^^^^^^---------------^^^^ - | | - | null pointer originates from here - | - = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> - -error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:88:5 + --> $DIR/invalid_null_args.rs:87:5 | LL | ptr::write_bytes::<usize>(ptr::null_mut(), 42, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^^^^^ @@ -274,7 +244,7 @@ LL | ptr::write_bytes::<usize>(ptr::null_mut(), 42, 0); = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:93:18 + --> $DIR/invalid_null_args.rs:92:18 | LL | let _a: u8 = ptr::read(const_ptr); | ^^^^^^^^^^^^^^^^^^^^ @@ -287,7 +257,7 @@ LL | let null_ptr = ptr::null_mut(); | ^^^^^^^^^^^^^^^ error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:100:5 + --> $DIR/invalid_null_args.rs:99:5 | LL | std::slice::from_raw_parts::<()>(ptr::null(), 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^ @@ -297,7 +267,7 @@ LL | std::slice::from_raw_parts::<()>(ptr::null(), 0); = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:102:5 + --> $DIR/invalid_null_args.rs:101:5 | LL | std::slice::from_raw_parts::<Zst>(ptr::null(), 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^ @@ -307,7 +277,7 @@ LL | std::slice::from_raw_parts::<Zst>(ptr::null(), 0); = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:104:5 + --> $DIR/invalid_null_args.rs:103:5 | LL | std::slice::from_raw_parts_mut::<()>(ptr::null_mut(), 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^ @@ -317,7 +287,7 @@ LL | std::slice::from_raw_parts_mut::<()>(ptr::null_mut(), 0); = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused - --> $DIR/invalid_null_args.rs:106:5 + --> $DIR/invalid_null_args.rs:105:5 | LL | std::slice::from_raw_parts_mut::<Zst>(ptr::null_mut(), 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^ @@ -326,5 +296,5 @@ LL | std::slice::from_raw_parts_mut::<Zst>(ptr::null_mut(), 0); | = help: for more information, visit <https://doc.rust-lang.org/std/ptr/index.html> and <https://doc.rust-lang.org/reference/behavior-considered-undefined.html> -error: aborting due to 31 previous errors +error: aborting due to 28 previous errors diff --git a/tests/ui/precondition-checks/read_volatile.rs b/tests/ui/precondition-checks/read_volatile.rs index fa1c2c827d7..33350dfbc4f 100644 --- a/tests/ui/precondition-checks/read_volatile.rs +++ b/tests/ui/precondition-checks/read_volatile.rs @@ -1,9 +1,7 @@ //@ run-crash //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes //@ error-pattern: unsafe precondition(s) violated: ptr::read_volatile requires -//@ revisions: null misaligned - -#![allow(invalid_null_arguments)] +//@ revisions: misaligned use std::ptr; @@ -11,8 +9,6 @@ fn main() { let src = [0u16; 2]; let src = src.as_ptr(); unsafe { - #[cfg(null)] - ptr::read_volatile(ptr::null::<u8>()); #[cfg(misaligned)] ptr::read_volatile(src.byte_add(1)); } diff --git a/tests/ui/precondition-checks/write_volatile.rs b/tests/ui/precondition-checks/write_volatile.rs index 25107871c39..d6ad6320e41 100644 --- a/tests/ui/precondition-checks/write_volatile.rs +++ b/tests/ui/precondition-checks/write_volatile.rs @@ -1,9 +1,7 @@ //@ run-crash //@ compile-flags: -Copt-level=3 -Cdebug-assertions=no -Zub-checks=yes //@ error-pattern: unsafe precondition(s) violated: ptr::write_volatile requires -//@ revisions: null misaligned - -#![allow(invalid_null_arguments)] +//@ revisions: misaligned use std::ptr; @@ -11,8 +9,6 @@ fn main() { let mut dst = [0u16; 2]; let mut dst = dst.as_mut_ptr(); unsafe { - #[cfg(null)] - ptr::write_volatile(ptr::null_mut::<u8>(), 1u8); #[cfg(misaligned)] ptr::write_volatile(dst.byte_add(1), 1u16); } |
