Skip to content

Commit

Permalink
Rollup merge of #124908 - saethlin:ref-casting_bigger_place_projectio…
Browse files Browse the repository at this point in the history
…n, r=fee1-dead

Handle field projections like slice indexing in invalid_reference_casting

r? `@Urgau`

I saw the implementation in #124761, and I was wondering if we also need to handle field access. We do. Without this PR, we get this errant diagnostic:
```
error: casting references to a bigger memory layout than the backing allocation is undefined behavior, even if the reference is unused
  --> /home/ben/rust/tests/ui/lint/reference_casting.rs:262:18
   |
LL |         let r = &mut v.0;
   |                      --- backing allocation comes from here
LL |         let ptr = r as *mut i32 as *mut Vec3<i32>;
   |                   ------------------------------- casting happend here
LL |         unsafe { *ptr = Vec3(0, 0, 0) }
   |                  ^^^^^^^^^^^^^^^^^^^^
   |
   = note: casting from `i32` (4 bytes) to `Vec3<i32>` (12 bytes)
```
  • Loading branch information
matthiaskrgr authored May 9, 2024
2 parents c49436d + 0ca1a94 commit 48b1e1a
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 1 deletion.
3 changes: 2 additions & 1 deletion compiler/rustc_lint/src/reference_casting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ fn is_cast_to_bigger_memory_layout<'tcx>(

// if the current expr looks like this `&mut expr[index]` then just looking
// at `expr[index]` won't give us the underlying allocation, so we just skip it
if let ExprKind::Index(..) = e_alloc.kind {
// the same logic applies field access like `&mut expr.field`
if let ExprKind::Index(..) | ExprKind::Field(..) = e_alloc.kind {
return None;
}

Expand Down
6 changes: 6 additions & 0 deletions tests/ui/lint/reference_casting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,12 @@ unsafe fn bigger_layout() {
let a3 = a2 as *mut u64;
unsafe { *a3 = 3 };
}

unsafe fn field_access(v: &mut Vec3<i32>) {
let r = &mut v.0;
let ptr = r as *mut i32 as *mut Vec3<i32>;
unsafe { *ptr = Vec3(0, 0, 0) }
}
}

const RAW_PTR: *mut u8 = 1 as *mut u8;
Expand Down

0 comments on commit 48b1e1a

Please sign in to comment.