diff options
Diffstat (limited to 'tests/ui/lint/reference_casting.rs')
-rw-r--r-- | tests/ui/lint/reference_casting.rs | 122 |
1 files changed, 88 insertions, 34 deletions
diff --git a/tests/ui/lint/reference_casting.rs b/tests/ui/lint/reference_casting.rs index 996382049..6c38bca3d 100644 --- a/tests/ui/lint/reference_casting.rs +++ b/tests/ui/lint/reference_casting.rs @@ -1,7 +1,6 @@ // check-fail #![feature(ptr_from_ref)] -#![deny(invalid_reference_casting)] extern "C" { // N.B., mutability can be easily incorrect in FFI calls -- as @@ -10,42 +9,97 @@ extern "C" { fn int_ffi(c: *mut i32); } -fn main() { +fn static_u8() -> &'static u8 { + &8 +} + +unsafe fn ref_to_mut() { + let num = &3i32; + + let _num = &mut *(num as *const i32 as *mut i32); + //~^ ERROR casting `&T` to `&mut T` is undefined behavior + let _num = &mut *(num as *const i32).cast_mut(); + //~^ ERROR casting `&T` to `&mut T` is undefined behavior + let _num = &mut *std::ptr::from_ref(num).cast_mut(); + //~^ ERROR casting `&T` to `&mut T` is undefined behavior + let _num = &mut *std::ptr::from_ref({ num }).cast_mut(); + //~^ ERROR casting `&T` to `&mut T` is undefined behavior + let _num = &mut *{ std::ptr::from_ref(num) }.cast_mut(); + //~^ ERROR casting `&T` to `&mut T` is undefined behavior + let _num = &mut *(std::ptr::from_ref({ num }) as *mut i32); + //~^ ERROR casting `&T` to `&mut T` is undefined behavior + let _num = &mut *(num as *const i32).cast::<i32>().cast_mut(); + //~^ ERROR casting `&T` to `&mut T` is undefined behavior + let _num = &mut *(num as *const i32).cast::<i32>().cast_mut().cast_const().cast_mut(); + //~^ ERROR casting `&T` to `&mut T` is undefined behavior + let _num = &mut *(std::ptr::from_ref(static_u8()) as *mut i32); + //~^ 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 deferred = num as *const i32 as *mut i32; + let _num = &mut *deferred; + //~^ ERROR casting `&T` to `&mut T` is undefined behavior + 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 _num = &mut *(num as *const _ as usize as *mut i32); + //~^ ERROR casting `&T` to `&mut T` is undefined behavior + + unsafe fn generic_ref_cast_mut<T>(this: &T) -> &mut T { + &mut *((this as *const _) as *mut _) + //~^ ERROR casting `&T` to `&mut T` is undefined behavior + } +} + +unsafe fn assign_to_ref() { let s = String::from("Hello"); let a = &s; - unsafe { - let num = &3i32; - let mut_num = &mut 3i32; + let num = &3i32; - (*(a as *const _ as *mut String)).push_str(" world"); - //~^ ERROR casting `&T` to `&mut T` is undefined behavior - *(a as *const _ as *mut _) = String::from("Replaced"); - //~^ ERROR casting `&T` to `&mut T` is undefined behavior - *(a as *const _ as *mut String) += " world"; - //~^ ERROR casting `&T` to `&mut T` is undefined behavior - let _num = &mut *(num as *const i32 as *mut i32); - //~^ ERROR casting `&T` to `&mut T` is undefined behavior - let _num = &mut *(num as *const i32).cast_mut(); - //~^ ERROR casting `&T` to `&mut T` is undefined behavior - let _num = *{ num as *const i32 }.cast_mut(); - //~^ ERROR casting `&T` to `&mut T` is undefined behavior - *std::ptr::from_ref(num).cast_mut() += 1; - //~^ ERROR casting `&T` to `&mut T` is undefined behavior - *std::ptr::from_ref({ num }).cast_mut() += 1; - //~^ ERROR casting `&T` to `&mut T` is undefined behavior - *{ std::ptr::from_ref(num) }.cast_mut() += 1; - //~^ ERROR casting `&T` to `&mut T` is undefined behavior - *(std::ptr::from_ref({ num }) as *mut i32) += 1; - //~^ ERROR casting `&T` to `&mut T` is undefined behavior + *(a as *const _ as *mut _) = String::from("Replaced"); + //~^ ERROR assigning to `&T` is undefined behavior + *(a as *const _ as *mut String) += " world"; + //~^ ERROR assigning to `&T` is undefined behavior + *std::ptr::from_ref(num).cast_mut() += 1; + //~^ ERROR assigning to `&T` is undefined behavior + *std::ptr::from_ref({ num }).cast_mut() += 1; + //~^ ERROR assigning to `&T` is undefined behavior + *{ std::ptr::from_ref(num) }.cast_mut() += 1; + //~^ ERROR assigning to `&T` is undefined behavior + *(std::ptr::from_ref({ num }) as *mut i32) += 1; + //~^ ERROR assigning to `&T` is undefined behavior + *std::mem::transmute::<_, *mut i32>(num) += 1; + //~^ ERROR assigning to `&T` is undefined behavior + + let value = num as *const i32 as *mut i32; + *value = 1; + //~^ ERROR assigning to `&T` is undefined behavior + *(num as *const i32).cast::<i32>().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 - // Shouldn't be warned against - println!("{}", *(num as *const _ as *const i16)); - println!("{}", *(mut_num as *mut _ as *mut i16)); - ffi(a.as_ptr() as *mut _); - int_ffi(num as *const _ as *mut _); - int_ffi(&3 as *const _ as *mut _); - let mut value = 3; - let value: *const i32 = &mut value; - *(value as *const i16 as *mut i16) = 42; + unsafe fn generic_assign_to_ref<T>(this: &T, a: T) { + *(this as *const _ as *mut _) = a; + //~^ ERROR assigning to `&T` is undefined behavior } } + +unsafe fn no_warn() { + let num = &3i32; + let mut_num = &mut 3i32; + let a = &String::from("ffi"); + + *(num as *const i32 as *mut i32); + println!("{}", *(num as *const _ as *const i16)); + println!("{}", *(mut_num as *mut _ as *mut i16)); + ffi(a.as_ptr() as *mut _); + int_ffi(num as *const _ as *mut _); + int_ffi(&3 as *const _ as *mut _); + let mut value = 3; + let value: *const i32 = &mut value; + *(value as *const i16 as *mut i16) = 42; +} + +fn main() {} |