From c23a457e72abe608715ac76f076f47dc42af07a5 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 30 May 2024 20:31:44 +0200 Subject: Merging upstream version 1.74.1+dfsg1. Signed-off-by: Daniel Baumann --- tests/ui/lint/reference_casting.rs | 62 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'tests/ui/lint/reference_casting.rs') diff --git a/tests/ui/lint/reference_casting.rs b/tests/ui/lint/reference_casting.rs index 6c38bca3d..fba8789e9 100644 --- a/tests/ui/lint/reference_casting.rs +++ b/tests/ui/lint/reference_casting.rs @@ -36,6 +36,12 @@ unsafe fn ref_to_mut() { //~^ ERROR casting `&T` to `&mut T` is undefined behavior let _num = &mut *std::mem::transmute::<_, *mut i32>(num); //~^ ERROR casting `&T` to `&mut T` is undefined behavior + let _num = &mut *(std::mem::transmute::<_, *mut i32>(num) as *mut i32); + //~^ ERROR casting `&T` to `&mut T` is undefined behavior + let _num = &mut *std::cell::UnsafeCell::raw_get( + //~^ ERROR casting `&T` to `&mut T` is undefined behavior + num as *const i32 as *const std::cell::UnsafeCell + ); let deferred = num as *const i32 as *mut i32; let _num = &mut *deferred; @@ -43,13 +49,35 @@ unsafe fn ref_to_mut() { let deferred = (std::ptr::from_ref(num) as *const i32 as *const i32).cast_mut() as *mut i32; let _num = &mut *deferred; //~^ ERROR casting `&T` to `&mut T` is undefined behavior + let deferred_rebind = deferred; + let _num = &mut *deferred_rebind; + //~^ ERROR casting `&T` to `&mut T` is undefined behavior let _num = &mut *(num as *const _ as usize as *mut i32); //~^ ERROR casting `&T` to `&mut T` is undefined behavior + let _num = &mut *(std::mem::transmute::<_, *mut _>(num as *const i32) as *mut i32); + //~^ ERROR casting `&T` to `&mut T` is undefined behavior + + static NUM: &'static i32 = &2; + let num = NUM as *const i32 as *mut i32; + let num = num; + let num = num; + let _num = &mut *num; + //~^ ERROR casting `&T` to `&mut T` is undefined behavior unsafe fn generic_ref_cast_mut(this: &T) -> &mut T { &mut *((this as *const _) as *mut _) //~^ ERROR casting `&T` to `&mut T` is undefined behavior } + + fn as_mut(x: &T) -> &mut T { + unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) } + //~^ ERROR casting `&T` to `&mut T` is undefined behavior + } + + fn as_mut_i32(x: &i32) -> &mut i32 { + unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) } + //~^ ERROR casting `&T` to `&mut T` is undefined behavior + } } unsafe fn assign_to_ref() { @@ -71,14 +99,30 @@ unsafe fn assign_to_ref() { //~^ ERROR assigning to `&T` is undefined behavior *std::mem::transmute::<_, *mut i32>(num) += 1; //~^ ERROR assigning to `&T` is undefined behavior + *(std::mem::transmute::<_, *mut i32>(num) as *mut i32) += 1; + //~^ ERROR assigning to `&T` is undefined behavior + std::ptr::write( + //~^ ERROR assigning to `&T` is undefined behavior + std::mem::transmute::<*const i32, *mut i32>(num), + -1i32, + ); let value = num as *const i32 as *mut i32; *value = 1; //~^ ERROR assigning to `&T` is undefined behavior + let value_rebind = value; + *value_rebind = 1; + //~^ ERROR assigning to `&T` is undefined behavior *(num as *const i32).cast::().cast_mut() = 2; //~^ ERROR assigning to `&T` is undefined behavior *(num as *const _ as usize as *mut i32) = 2; //~^ ERROR assigning to `&T` is undefined behavior + std::ptr::write(value, 2); + //~^ ERROR assigning to `&T` is undefined behavior + std::ptr::write_unaligned(value, 2); + //~^ ERROR assigning to `&T` is undefined behavior + std::ptr::write_volatile(value, 2); + //~^ ERROR assigning to `&T` is undefined behavior unsafe fn generic_assign_to_ref(this: &T, a: T) { *(this as *const _ as *mut _) = a; @@ -86,6 +130,7 @@ unsafe fn assign_to_ref() { } } +const RAW_PTR: *mut u8 = 1 as *mut u8; unsafe fn no_warn() { let num = &3i32; let mut_num = &mut 3i32; @@ -100,6 +145,23 @@ unsafe fn no_warn() { let mut value = 3; let value: *const i32 = &mut value; *(value as *const i16 as *mut i16) = 42; + *RAW_PTR = 42; // RAW_PTR is defined outside the function body, + // make sure we don't ICE on it when trying to + // determine if we should lint on it or not. + + fn safe_as_mut(x: &std::cell::UnsafeCell) -> &mut T { + unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) } + } + + fn cell_as_mut(x: &std::cell::Cell) -> &mut i32 { + unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) } + } + + #[repr(transparent)] + struct DoesContainUnsafeCell(std::cell::UnsafeCell); + fn safe_as_mut2(x: &DoesContainUnsafeCell) -> &mut DoesContainUnsafeCell { + unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) } + } } fn main() {} -- cgit v1.2.3