Skip to content

Add lint against integer to pointer transmutes #144531

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

Urgau
Copy link
Member

@Urgau Urgau commented Jul 27, 2025

integer_to_ptr_transmutes

warn-by-default

The integer_to_ptr_transmutes lint detects integer to pointer transmutes where the resulting pointers are undefined behavior to dereference.

Example

fn foo(a: usize) -> *const u8 {
    unsafe {
        std::mem::transmute::<usize, *const u8>(a)
    }
}
warning: transmuting an integer to a pointer creates a pointer without provenance
   --> a.rs:1:9
    |
158 |         std::mem::transmute::<usize, *const u8>(a)
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = 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
help: use `as` cast instead to use a previously exposed provenance
    |
158 -         std::mem::transmute::<usize, *const u8>(a)
158 +         std::ptr::with_exposed_provenance::<u8>(a)
    |

Explanation

Any attempt to use the resulting pointers are undefined behavior as the resulting pointers won't have any provenance.

Alternatively, std::ptr::with_exposed_provenance should be used, as they do not carry the provenance requirement or if the wanting to create pointers without provenance std::ptr::without_provenance_mut should be used.

See std::mem::transmute in the reference for more details.


People are getting tripped up on this, see #128409 and #141220. There are >90 cases like these on GitHub search.

Fixes rust-lang/rust-clippy#13140
Fixes #141220

@rustbot labels +I-lang-nominated +T-lang
cc @traviscross
r? compiler

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Jul 27, 2025
@rustbot
Copy link
Collaborator

rustbot commented Jul 27, 2025

The Miri subtree was changed

cc @rust-lang/miri

@rustbot rustbot added I-lang-nominated Nominated for discussion during a lang team meeting. T-lang Relevant to the language team labels Jul 27, 2025
@RalfJung
Copy link
Member

for more information about exposed provenance

This is confusing since exposed provenance is not previously mentioned in the error message.

use std::ptr::without_provenance_mut to create a pointer without provenance

The error should probably make it clear that int-to-ptr transmute also create a pointer without provenance.

@rust-log-analyzer

This comment has been minimized.

@Urgau Urgau force-pushed the int_to_ptr_transmutes branch from b8f46d7 to 950af22 Compare July 27, 2025 13:08
@Urgau
Copy link
Member Author

Urgau commented Jul 27, 2025

I have adjusted the diagnostics to make it clear that int-to-ptr transmute also create a pointer without transmute and added a note about exposed provenance (since suggestions always go at the end).

@Urgau Urgau force-pushed the int_to_ptr_transmutes branch from 950af22 to 66d7c24 Compare July 27, 2025 13:38
Comment on lines +20 to +42
unsafe fn should_not_lint(a: usize) {
let _ptr = unsafe { std::mem::transmute::<usize, *const u8>(0usize) }; // linted by other lints
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the other lint? I'm not immediately seeing another diagnostic in testing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(We have deref-nullptr, but that fires when dereferencing it.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For references, we lint on transmutes with the 0 literal with the invalid_value lint:

warning: the type `&i32` does not permit zero-initialization
 --> src/lib.rs:2:39
  |
2 |     let _val: &'static i32 = unsafe { std::mem::transmute(0usize) };
  |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |                                       |
  |                                       this code causes undefined behavior when executed
  |                                       help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
  |
  = note: references must be non-null
  = note: `#[warn(invalid_value)]` on by default

For pointer we lint on some function with the invalid_null_arguments lint:

error: calling this function with a null pointer is undefined behavior, even if the result of the function is unused
  --> /home/archie/Projects/RustProjects/rust/tests/ui/lint/invalid_null_args.rs:27:23
   |
LL |     let _: &[usize] = std::slice::from_raw_parts(mem::transmute(0usize), 0);
   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------^^^^^
   |                                                                 |
   |                                                                 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>

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could not care about the invalid_null_arguments lint and lint on transmutes to raw pointer.

For references I think we should keep it under the invalid_value lint.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like nobody will be surprised that transmuting 0 to a pointer will not give you something you can dereference...

Copy link
Member

@samueltardieu samueltardieu Jul 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even in the context of #141260? (I haven't checked carefully, it just rang a bell)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For out-of-AM volatile accesses, provenance does not matter.

@traviscross traviscross added P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang and removed T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Jul 27, 2025
@rust-log-analyzer

This comment has been minimized.

@Urgau Urgau force-pushed the int_to_ptr_transmutes branch from 66d7c24 to f29459b Compare July 27, 2025 15:43
@Urgau Urgau force-pushed the int_to_ptr_transmutes branch from f29459b to a2f8fde Compare July 27, 2025 16:17
@rust-log-analyzer

This comment has been minimized.

@Urgau Urgau force-pushed the int_to_ptr_transmutes branch from a2f8fde to eec7ccb Compare July 27, 2025 19:35
@rustbot rustbot added the T-clippy Relevant to the Clippy team. label Jul 27, 2025
@rustbot
Copy link
Collaborator

rustbot commented Jul 27, 2025

Some changes occurred in src/tools/clippy

cc @rust-lang/clippy

@Urgau Urgau removed the T-clippy Relevant to the Clippy team. label Jul 27, 2025
@blyxyas blyxyas added T-lang Relevant to the language team and removed T-lang Relevant to the language team labels Jul 27, 2025
@rust-log-analyzer

This comment has been minimized.

@Urgau Urgau force-pushed the int_to_ptr_transmutes branch from eec7ccb to 186956d Compare July 27, 2025 21:07
@rustbot rustbot added the T-clippy Relevant to the Clippy team. label Jul 27, 2025
@traviscross traviscross removed the T-clippy Relevant to the Clippy team. label Jul 28, 2025
@traviscross
Copy link
Contributor

Seems like a clear win. Thanks @Urgau. Let's...

@rfcbot fcp merge

@rfcbot
Copy link
Collaborator

rfcbot commented Jul 28, 2025

Team member @traviscross has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

cc @rust-lang/lang-advisors: FCP proposed for lang, please feel free to register concerns.
See this document for info about what commands tagged team members can give me.

@rfcbot rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. labels Jul 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. I-lang-nominated Nominated for discussion during a lang team meeting. P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-lang Relevant to the language team
Projects
None yet
9 participants