about summary refs log tree commit diff
path: root/tests/ui/lint
diff options
context:
space:
mode:
authorUrgau <urgau@numericable.fr>2025-07-27 12:56:02 +0200
committerUrgau <urgau@numericable.fr>2025-08-24 00:03:53 +0200
commitd4cbd9a440d0106fed53cc173dd539492f95f382 (patch)
tree99d20ecc3ad9f4236a8cec430ffb430f2f7d7993 /tests/ui/lint
parentc5a6a7bdd89f099544fa0d3fad4d833d238377ad (diff)
downloadrust-d4cbd9a440d0106fed53cc173dd539492f95f382.tar.gz
rust-d4cbd9a440d0106fed53cc173dd539492f95f382.zip
Add lint against integer to pointer transmutes
Diffstat (limited to 'tests/ui/lint')
-rw-r--r--tests/ui/lint/int_to_ptr.fixed47
-rw-r--r--tests/ui/lint/int_to_ptr.rs47
-rw-r--r--tests/ui/lint/int_to_ptr.stderr171
3 files changed, 265 insertions, 0 deletions
diff --git a/tests/ui/lint/int_to_ptr.fixed b/tests/ui/lint/int_to_ptr.fixed
new file mode 100644
index 00000000000..8f373492e6f
--- /dev/null
+++ b/tests/ui/lint/int_to_ptr.fixed
@@ -0,0 +1,47 @@
+// Checks for the `integer_to_pointer_transmutes` lint
+
+//@ check-pass
+//@ run-rustfix
+
+#![allow(unused_unsafe)]
+#![allow(dead_code)]
+
+unsafe fn should_lint(a: usize) {
+    let _ptr: *const u8 = unsafe { std::ptr::with_exposed_provenance::<u8>(a) };
+    //~^ WARN transmuting an integer to a pointer
+    let _ptr: *mut u8 = unsafe { std::ptr::with_exposed_provenance_mut::<u8>(a) };
+    //~^ WARN transmuting an integer to a pointer
+    let _ref: &'static u8 = unsafe { &*std::ptr::with_exposed_provenance::<u8>(a) };
+    //~^ WARN transmuting an integer to a pointer
+    let _ref: &'static mut u8 = unsafe { &mut *std::ptr::with_exposed_provenance_mut::<u8>(a) };
+    //~^ WARN transmuting an integer to a pointer
+
+    let _ptr = unsafe { std::ptr::with_exposed_provenance::<u8>(42usize) };
+    //~^ WARN transmuting an integer to a pointer
+    let _ptr = unsafe { std::ptr::with_exposed_provenance::<u8>(a + a) };
+    //~^ WARN transmuting an integer to a pointer
+}
+
+const unsafe fn should_lintin_const(a: usize) {
+    let _ptr: *const u8 = unsafe { std::ptr::with_exposed_provenance::<u8>(a) };
+    //~^ WARN transmuting an integer to a pointer
+    let _ptr: *mut u8 = unsafe { std::ptr::with_exposed_provenance_mut::<u8>(a) };
+    //~^ WARN transmuting an integer to a pointer
+    let _ref: &'static u8 = unsafe { &*std::ptr::with_exposed_provenance::<u8>(a) };
+    //~^ WARN transmuting an integer to a pointer
+    let _ref: &'static mut u8 = unsafe { &mut *std::ptr::with_exposed_provenance_mut::<u8>(a) };
+    //~^ WARN transmuting an integer to a pointer
+
+    let _ptr = unsafe { std::ptr::with_exposed_provenance::<u8>(42usize) };
+    //~^ WARN transmuting an integer to a pointer
+    let _ptr = unsafe { std::ptr::with_exposed_provenance::<u8>(a + a) };
+    //~^ WARN transmuting an integer to a pointer
+}
+
+unsafe fn should_not_lint(a: usize) {
+    let _ptr = unsafe { std::mem::transmute::<usize, *const u8>(0usize) }; // linted by other lints
+    let _ptr = unsafe { std::mem::transmute::<usize, *const ()>(a) }; // inner type is a ZST
+    let _ptr = unsafe { std::mem::transmute::<usize, fn()>(a) }; // omit fn-ptr for now
+}
+
+fn main() {}
diff --git a/tests/ui/lint/int_to_ptr.rs b/tests/ui/lint/int_to_ptr.rs
new file mode 100644
index 00000000000..7f60da47b85
--- /dev/null
+++ b/tests/ui/lint/int_to_ptr.rs
@@ -0,0 +1,47 @@
+// Checks for the `integer_to_pointer_transmutes` lint
+
+//@ check-pass
+//@ run-rustfix
+
+#![allow(unused_unsafe)]
+#![allow(dead_code)]
+
+unsafe fn should_lint(a: usize) {
+    let _ptr: *const u8 = unsafe { std::mem::transmute::<usize, *const u8>(a) };
+    //~^ WARN transmuting an integer to a pointer
+    let _ptr: *mut u8 = unsafe { std::mem::transmute::<usize, *mut u8>(a) };
+    //~^ WARN transmuting an integer to a pointer
+    let _ref: &'static u8 = unsafe { std::mem::transmute::<usize, &'static u8>(a) };
+    //~^ WARN transmuting an integer to a pointer
+    let _ref: &'static mut u8 = unsafe { std::mem::transmute::<usize, &'static mut u8>(a) };
+    //~^ WARN transmuting an integer to a pointer
+
+    let _ptr = unsafe { std::mem::transmute::<usize, *const u8>(42usize) };
+    //~^ WARN transmuting an integer to a pointer
+    let _ptr = unsafe { std::mem::transmute::<usize, *const u8>(a + a) };
+    //~^ WARN transmuting an integer to a pointer
+}
+
+const unsafe fn should_lintin_const(a: usize) {
+    let _ptr: *const u8 = unsafe { std::mem::transmute::<usize, *const u8>(a) };
+    //~^ WARN transmuting an integer to a pointer
+    let _ptr: *mut u8 = unsafe { std::mem::transmute::<usize, *mut u8>(a) };
+    //~^ WARN transmuting an integer to a pointer
+    let _ref: &'static u8 = unsafe { std::mem::transmute::<usize, &'static u8>(a) };
+    //~^ WARN transmuting an integer to a pointer
+    let _ref: &'static mut u8 = unsafe { std::mem::transmute::<usize, &'static mut u8>(a) };
+    //~^ WARN transmuting an integer to a pointer
+
+    let _ptr = unsafe { std::mem::transmute::<usize, *const u8>(42usize) };
+    //~^ WARN transmuting an integer to a pointer
+    let _ptr = unsafe { std::mem::transmute::<usize, *const u8>(a + a) };
+    //~^ WARN transmuting an integer to a pointer
+}
+
+unsafe fn should_not_lint(a: usize) {
+    let _ptr = unsafe { std::mem::transmute::<usize, *const u8>(0usize) }; // linted by other lints
+    let _ptr = unsafe { std::mem::transmute::<usize, *const ()>(a) }; // inner type is a ZST
+    let _ptr = unsafe { std::mem::transmute::<usize, fn()>(a) }; // omit fn-ptr for now
+}
+
+fn main() {}
diff --git a/tests/ui/lint/int_to_ptr.stderr b/tests/ui/lint/int_to_ptr.stderr
new file mode 100644
index 00000000000..437f6442397
--- /dev/null
+++ b/tests/ui/lint/int_to_ptr.stderr
@@ -0,0 +1,171 @@
+warning: transmuting an integer to a pointer creates a pointer without provenance
+  --> $DIR/int_to_ptr.rs:10:36
+   |
+LL |     let _ptr: *const u8 = unsafe { std::mem::transmute::<usize, *const u8>(a) };
+   |                                    ----------------------------------------^^
+   |                                    |
+   |                                    help: use `std::ptr::with_exposed_provenance` instead to use a previously exposed provenance: `std::ptr::with_exposed_provenance::<u8>(`
+   |
+   = note: this is dangerous because dereferencing the resulting pointer is undefined behavior
+   = note: exposed provenance semantics can be used to create a pointer based on some previously exposed provenance
+   = help: if you truly mean to create a pointer without provenance, use `std::ptr::without_provenance_mut`
+   = help: for more information about transmute, see <https://doc.rust-lang.org/std/mem/fn.transmute.html#transmutation-between-pointers-and-integers>
+   = help: for more information about exposed provenance, see <https://doc.rust-lang.org/std/ptr/index.html#exposed-provenance>
+   = note: `#[warn(integer_to_ptr_transmutes)]` on by default
+
+warning: transmuting an integer to a pointer creates a pointer without provenance
+  --> $DIR/int_to_ptr.rs:12:34
+   |
+LL |     let _ptr: *mut u8 = unsafe { std::mem::transmute::<usize, *mut u8>(a) };
+   |                                  --------------------------------------^^
+   |                                  |
+   |                                  help: use `std::ptr::with_exposed_provenance_mut` instead to use a previously exposed provenance: `std::ptr::with_exposed_provenance_mut::<u8>(`
+   |
+   = note: this is dangerous because dereferencing the resulting pointer is undefined behavior
+   = note: exposed provenance semantics can be used to create a pointer based on some previously exposed provenance
+   = help: if you truly mean to create a pointer without provenance, use `std::ptr::without_provenance_mut`
+   = help: for more information about transmute, see <https://doc.rust-lang.org/std/mem/fn.transmute.html#transmutation-between-pointers-and-integers>
+   = help: for more information about exposed provenance, see <https://doc.rust-lang.org/std/ptr/index.html#exposed-provenance>
+
+warning: transmuting an integer to a pointer creates a pointer without provenance
+  --> $DIR/int_to_ptr.rs:14:38
+   |
+LL |     let _ref: &'static u8 = unsafe { std::mem::transmute::<usize, &'static u8>(a) };
+   |                                      ------------------------------------------^^
+   |                                      |
+   |                                      help: use `std::ptr::with_exposed_provenance` instead to use a previously exposed provenance: `&*std::ptr::with_exposed_provenance::<u8>(`
+   |
+   = note: this is dangerous because dereferencing the resulting pointer is undefined behavior
+   = note: exposed provenance semantics can be used to create a pointer based on some previously exposed provenance
+   = help: if you truly mean to create a pointer without provenance, use `std::ptr::without_provenance_mut`
+   = help: for more information about transmute, see <https://doc.rust-lang.org/std/mem/fn.transmute.html#transmutation-between-pointers-and-integers>
+   = help: for more information about exposed provenance, see <https://doc.rust-lang.org/std/ptr/index.html#exposed-provenance>
+
+warning: transmuting an integer to a pointer creates a pointer without provenance
+  --> $DIR/int_to_ptr.rs:16:42
+   |
+LL |     let _ref: &'static mut u8 = unsafe { std::mem::transmute::<usize, &'static mut u8>(a) };
+   |                                          ----------------------------------------------^^
+   |                                          |
+   |                                          help: use `std::ptr::with_exposed_provenance_mut` instead to use a previously exposed provenance: `&mut *std::ptr::with_exposed_provenance_mut::<u8>(`
+   |
+   = note: this is dangerous because dereferencing the resulting pointer is undefined behavior
+   = note: exposed provenance semantics can be used to create a pointer based on some previously exposed provenance
+   = help: if you truly mean to create a pointer without provenance, use `std::ptr::without_provenance_mut`
+   = help: for more information about transmute, see <https://doc.rust-lang.org/std/mem/fn.transmute.html#transmutation-between-pointers-and-integers>
+   = help: for more information about exposed provenance, see <https://doc.rust-lang.org/std/ptr/index.html#exposed-provenance>
+
+warning: transmuting an integer to a pointer creates a pointer without provenance
+  --> $DIR/int_to_ptr.rs:19:25
+   |
+LL |     let _ptr = unsafe { std::mem::transmute::<usize, *const u8>(42usize) };
+   |                         ----------------------------------------^^^^^^^^
+   |                         |
+   |                         help: use `std::ptr::with_exposed_provenance` instead to use a previously exposed provenance: `std::ptr::with_exposed_provenance::<u8>(`
+   |
+   = note: this is dangerous because dereferencing the resulting pointer is undefined behavior
+   = note: exposed provenance semantics can be used to create a pointer based on some previously exposed provenance
+   = help: if you truly mean to create a pointer without provenance, use `std::ptr::without_provenance_mut`
+   = help: for more information about transmute, see <https://doc.rust-lang.org/std/mem/fn.transmute.html#transmutation-between-pointers-and-integers>
+   = help: for more information about exposed provenance, see <https://doc.rust-lang.org/std/ptr/index.html#exposed-provenance>
+
+warning: transmuting an integer to a pointer creates a pointer without provenance
+  --> $DIR/int_to_ptr.rs:21:25
+   |
+LL |     let _ptr = unsafe { std::mem::transmute::<usize, *const u8>(a + a) };
+   |                         ----------------------------------------^^^^^^
+   |                         |
+   |                         help: use `std::ptr::with_exposed_provenance` instead to use a previously exposed provenance: `std::ptr::with_exposed_provenance::<u8>(`
+   |
+   = note: this is dangerous because dereferencing the resulting pointer is undefined behavior
+   = note: exposed provenance semantics can be used to create a pointer based on some previously exposed provenance
+   = help: if you truly mean to create a pointer without provenance, use `std::ptr::without_provenance_mut`
+   = help: for more information about transmute, see <https://doc.rust-lang.org/std/mem/fn.transmute.html#transmutation-between-pointers-and-integers>
+   = help: for more information about exposed provenance, see <https://doc.rust-lang.org/std/ptr/index.html#exposed-provenance>
+
+warning: transmuting an integer to a pointer creates a pointer without provenance
+  --> $DIR/int_to_ptr.rs:26:36
+   |
+LL |     let _ptr: *const u8 = unsafe { std::mem::transmute::<usize, *const u8>(a) };
+   |                                    ----------------------------------------^^
+   |                                    |
+   |                                    help: use `std::ptr::with_exposed_provenance` instead to use a previously exposed provenance: `std::ptr::with_exposed_provenance::<u8>(`
+   |
+   = note: this is dangerous because dereferencing the resulting pointer is undefined behavior
+   = note: exposed provenance semantics can be used to create a pointer based on some previously exposed provenance
+   = help: if you truly mean to create a pointer without provenance, use `std::ptr::without_provenance_mut`
+   = help: for more information about transmute, see <https://doc.rust-lang.org/std/mem/fn.transmute.html#transmutation-between-pointers-and-integers>
+   = help: for more information about exposed provenance, see <https://doc.rust-lang.org/std/ptr/index.html#exposed-provenance>
+
+warning: transmuting an integer to a pointer creates a pointer without provenance
+  --> $DIR/int_to_ptr.rs:28:34
+   |
+LL |     let _ptr: *mut u8 = unsafe { std::mem::transmute::<usize, *mut u8>(a) };
+   |                                  --------------------------------------^^
+   |                                  |
+   |                                  help: use `std::ptr::with_exposed_provenance_mut` instead to use a previously exposed provenance: `std::ptr::with_exposed_provenance_mut::<u8>(`
+   |
+   = note: this is dangerous because dereferencing the resulting pointer is undefined behavior
+   = note: exposed provenance semantics can be used to create a pointer based on some previously exposed provenance
+   = help: if you truly mean to create a pointer without provenance, use `std::ptr::without_provenance_mut`
+   = help: for more information about transmute, see <https://doc.rust-lang.org/std/mem/fn.transmute.html#transmutation-between-pointers-and-integers>
+   = help: for more information about exposed provenance, see <https://doc.rust-lang.org/std/ptr/index.html#exposed-provenance>
+
+warning: transmuting an integer to a pointer creates a pointer without provenance
+  --> $DIR/int_to_ptr.rs:30:38
+   |
+LL |     let _ref: &'static u8 = unsafe { std::mem::transmute::<usize, &'static u8>(a) };
+   |                                      ------------------------------------------^^
+   |                                      |
+   |                                      help: use `std::ptr::with_exposed_provenance` instead to use a previously exposed provenance: `&*std::ptr::with_exposed_provenance::<u8>(`
+   |
+   = note: this is dangerous because dereferencing the resulting pointer is undefined behavior
+   = note: exposed provenance semantics can be used to create a pointer based on some previously exposed provenance
+   = help: if you truly mean to create a pointer without provenance, use `std::ptr::without_provenance_mut`
+   = help: for more information about transmute, see <https://doc.rust-lang.org/std/mem/fn.transmute.html#transmutation-between-pointers-and-integers>
+   = help: for more information about exposed provenance, see <https://doc.rust-lang.org/std/ptr/index.html#exposed-provenance>
+
+warning: transmuting an integer to a pointer creates a pointer without provenance
+  --> $DIR/int_to_ptr.rs:32:42
+   |
+LL |     let _ref: &'static mut u8 = unsafe { std::mem::transmute::<usize, &'static mut u8>(a) };
+   |                                          ----------------------------------------------^^
+   |                                          |
+   |                                          help: use `std::ptr::with_exposed_provenance_mut` instead to use a previously exposed provenance: `&mut *std::ptr::with_exposed_provenance_mut::<u8>(`
+   |
+   = note: this is dangerous because dereferencing the resulting pointer is undefined behavior
+   = note: exposed provenance semantics can be used to create a pointer based on some previously exposed provenance
+   = help: if you truly mean to create a pointer without provenance, use `std::ptr::without_provenance_mut`
+   = help: for more information about transmute, see <https://doc.rust-lang.org/std/mem/fn.transmute.html#transmutation-between-pointers-and-integers>
+   = help: for more information about exposed provenance, see <https://doc.rust-lang.org/std/ptr/index.html#exposed-provenance>
+
+warning: transmuting an integer to a pointer creates a pointer without provenance
+  --> $DIR/int_to_ptr.rs:35:25
+   |
+LL |     let _ptr = unsafe { std::mem::transmute::<usize, *const u8>(42usize) };
+   |                         ----------------------------------------^^^^^^^^
+   |                         |
+   |                         help: use `std::ptr::with_exposed_provenance` instead to use a previously exposed provenance: `std::ptr::with_exposed_provenance::<u8>(`
+   |
+   = note: this is dangerous because dereferencing the resulting pointer is undefined behavior
+   = note: exposed provenance semantics can be used to create a pointer based on some previously exposed provenance
+   = help: if you truly mean to create a pointer without provenance, use `std::ptr::without_provenance_mut`
+   = help: for more information about transmute, see <https://doc.rust-lang.org/std/mem/fn.transmute.html#transmutation-between-pointers-and-integers>
+   = help: for more information about exposed provenance, see <https://doc.rust-lang.org/std/ptr/index.html#exposed-provenance>
+
+warning: transmuting an integer to a pointer creates a pointer without provenance
+  --> $DIR/int_to_ptr.rs:37:25
+   |
+LL |     let _ptr = unsafe { std::mem::transmute::<usize, *const u8>(a + a) };
+   |                         ----------------------------------------^^^^^^
+   |                         |
+   |                         help: use `std::ptr::with_exposed_provenance` instead to use a previously exposed provenance: `std::ptr::with_exposed_provenance::<u8>(`
+   |
+   = note: this is dangerous because dereferencing the resulting pointer is undefined behavior
+   = note: exposed provenance semantics can be used to create a pointer based on some previously exposed provenance
+   = help: if you truly mean to create a pointer without provenance, use `std::ptr::without_provenance_mut`
+   = help: for more information about transmute, see <https://doc.rust-lang.org/std/mem/fn.transmute.html#transmutation-between-pointers-and-integers>
+   = help: for more information about exposed provenance, see <https://doc.rust-lang.org/std/ptr/index.html#exposed-provenance>
+
+warning: 12 warnings emitted
+