Skip to content
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

transmute_ptr_to_ptr: exclude instances between reference where itself is not definitely UB? #11356

Open
KisaragiEffective opened this issue Aug 19, 2023 · 2 comments
Labels
C-question Category: Questions

Comments

@KisaragiEffective
Copy link
Contributor

KisaragiEffective commented Aug 19, 2023

cc #6372

Description

transmute_ptr_to_ptr is too noisy for instance of between references even it is pedantic currently IMO.

This issue suggests avoid triggering if following conditions are met, because those do not trigger UBs:

  1. the call does not extends lifetime, nor change it to unrelated one.
  2. at least one of following conditions are met
    1. the Src is an enum and it has #[repr(C)] or #[repr($integer)] or #[repr(transparent)], and Dst is corresponding type.
    2. the Src is an struct and it has #[repr(transparent)], and Dst is reference to the inner type.
    3. the Src is an struct which has single field and #[repr(C)], and Dst is reference to the field type.

Purpose

The lint should not be warn on &'a E ~> &'a E::Repr (where E is any field-less enum), &'a Transparent ~> &'a Transparent::Inner (where Transparent is struct with #[repr(transparent)]). The former can be achieved by primitive cast, but latter is not:

#[repr(C)] // also applicable if layout is i*, u*, or transparent
enum ExpReprC {
    Zero = 0,
}

#[repr(transparent)] // also applicable if layout is C
struct Transparent(u8);

fn main() {
    let m: ExpReprC = ExpReprC::Zero;
    let x: &u8 = unsafe { std::mem::transmute(&m) };
    
    let m: Transparent = Transparent(42);
    let x: &u8 = unsafe { std::mem::transmute(&m) };
    
}

Version

rustc 1.73.0-nightly (31395ec38 2023-07-24)
binary: rustc            
commit-hash: 31395ec38250b60b380fd3c27e94756aba3557de
commit-date: 2023-07-24  
host: x86_64-unknown-linux-gnu
release: 1.73.0-nightly  
LLVM version: 16.0.5

Additional Labels

@rustbot label C-question

@rustbot rustbot added the C-question Category: Questions label Aug 19, 2023
@asquared31415
Copy link
Contributor

All of these cases would be better served by &x.field or &x as REPR_TYPE, which does the same operation, but restricts the lifetime and ensures that the types are correct.

the call does not extends lifetime, nor change it to unrelated one.
transmute returns an "unbound lifetime" so whether a lifetime change happens is very liable to change with small inference changes in the program.

It's perfectly fine that a pedantic lint lints on possible sound but fragile code.

@Jarcho
Copy link
Contributor

Jarcho commented Aug 22, 2023

&(x as REPR_TYPE) doesn't work as it creates a reference to a temporary. (&x as REPR_TYPE is casting the reference)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-question Category: Questions
Projects
None yet
Development

No branches or pull requests

4 participants