summaryrefslogtreecommitdiffstats
path: root/tests/ui/lint/reference_casting.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
commitc23a457e72abe608715ac76f076f47dc42af07a5 (patch)
tree2772049aaf84b5c9d0ed12ec8d86812f7a7904b6 /tests/ui/lint/reference_casting.rs
parentReleasing progress-linux version 1.73.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-c23a457e72abe608715ac76f076f47dc42af07a5.tar.xz
rustc-c23a457e72abe608715ac76f076f47dc42af07a5.zip
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/lint/reference_casting.rs')
-rw-r--r--tests/ui/lint/reference_casting.rs62
1 files changed, 62 insertions, 0 deletions
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<i32>
+ );
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<T>(this: &T) -> &mut T {
&mut *((this as *const _) as *mut _)
//~^ ERROR casting `&T` to `&mut T` is undefined behavior
}
+
+ fn as_mut<T>(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::<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
+ 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<T>(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<T>(x: &std::cell::UnsafeCell<T>) -> &mut T {
+ unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) }
+ }
+
+ fn cell_as_mut(x: &std::cell::Cell<i32>) -> &mut i32 {
+ unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) }
+ }
+
+ #[repr(transparent)]
+ struct DoesContainUnsafeCell(std::cell::UnsafeCell<i32>);
+ fn safe_as_mut2(x: &DoesContainUnsafeCell) -> &mut DoesContainUnsafeCell {
+ unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) }
+ }
}
fn main() {}