about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorUrgau <urgau@numericable.fr>2023-07-14 22:25:47 +0200
committerUrgau <urgau@numericable.fr>2023-07-29 12:20:59 +0200
commit20a6b571063d33c4b1a786c558f74edbda3012ea (patch)
treeaed81caf56603e7ca6e9b8ea1ff8871df04fdf44 /tests
parent50a46710a9c6942751930fa963e0d70d84128859 (diff)
downloadrust-20a6b571063d33c4b1a786c558f74edbda3012ea.tar.gz
rust-20a6b571063d33c4b1a786c558f74edbda3012ea.zip
Improve diagnostics of the invalid_reference_casting lint
Diffstat (limited to 'tests')
-rw-r--r--tests/ui/lint/reference_casting.rs93
-rw-r--r--tests/ui/lint/reference_casting.stderr96
2 files changed, 121 insertions, 68 deletions
diff --git a/tests/ui/lint/reference_casting.rs b/tests/ui/lint/reference_casting.rs
index aa946038c99..6e70626ef99 100644
--- a/tests/ui/lint/reference_casting.rs
+++ b/tests/ui/lint/reference_casting.rs
@@ -9,42 +9,63 @@ extern "C" {
     fn int_ffi(c: *mut i32);
 }
 
-fn main() {
+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 deferred = num as *const i32 as *mut i32;
+    let _num = &mut *deferred;
+    //~^ 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;
-
-        *(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
-        *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
-        let value = num as *const i32 as *mut i32;
-        *value = 1;
-        //~^ ERROR casting `&T` to `&mut T` is undefined behavior
-
-        // Shouldn't be warned against
-        *(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;
-    }
+    let num = &3i32;
+
+    *(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
+    let value = num as *const i32 as *mut i32;
+    *value = 1;
+    //~^ 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() {}
diff --git a/tests/ui/lint/reference_casting.stderr b/tests/ui/lint/reference_casting.stderr
index 22bc66264d0..02b23600557 100644
--- a/tests/ui/lint/reference_casting.stderr
+++ b/tests/ui/lint/reference_casting.stderr
@@ -1,60 +1,92 @@
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:19:9
+  --> $DIR/reference_casting.rs:15:16
    |
-LL |         *(a as *const _ as *mut _) = String::from("Replaced");
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     let _num = &mut *(num as *const i32 as *mut i32);
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `#[deny(invalid_reference_casting)]` on by default
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:21:9
+  --> $DIR/reference_casting.rs:17:16
    |
-LL |         *(a as *const _ as *mut String) += " world";
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     let _num = &mut *(num as *const i32).cast_mut();
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:23:20
+  --> $DIR/reference_casting.rs:19:16
    |
-LL |         let _num = &mut *(num as *const i32 as *mut i32);
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     let _num = &mut *std::ptr::from_ref(num).cast_mut();
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:25:20
+  --> $DIR/reference_casting.rs:21:16
    |
-LL |         let _num = &mut *(num as *const i32).cast_mut();
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     let _num = &mut *std::ptr::from_ref({ num }).cast_mut();
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:27:9
+  --> $DIR/reference_casting.rs:23:16
    |
-LL |         *std::ptr::from_ref(num).cast_mut() += 1;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     let _num = &mut *{ std::ptr::from_ref(num) }.cast_mut();
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:29:9
+  --> $DIR/reference_casting.rs:25:16
    |
-LL |         *std::ptr::from_ref({ num }).cast_mut() += 1;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     let _num = &mut *(std::ptr::from_ref({ num }) as *mut i32);
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:31:9
+  --> $DIR/reference_casting.rs:29:16
    |
-LL |         *{ std::ptr::from_ref(num) }.cast_mut() += 1;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     let deferred = num as *const i32 as *mut i32;
+   |                    ----------------------------- casting happend here
+LL |     let _num = &mut *deferred;
+   |                ^^^^^^^^^^^^^^
 
-error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:33:9
+error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
+  --> $DIR/reference_casting.rs:38:5
    |
-LL |         *(std::ptr::from_ref({ num }) as *mut i32) += 1;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     *(a as *const _ as *mut _) = String::from("Replaced");
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:36:9
+error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
+  --> $DIR/reference_casting.rs:40:5
+   |
+LL |     *(a as *const _ as *mut String) += " world";
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
+  --> $DIR/reference_casting.rs:42:5
+   |
+LL |     *std::ptr::from_ref(num).cast_mut() += 1;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
+  --> $DIR/reference_casting.rs:44:5
+   |
+LL |     *std::ptr::from_ref({ num }).cast_mut() += 1;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
+  --> $DIR/reference_casting.rs:46:5
+   |
+LL |     *{ std::ptr::from_ref(num) }.cast_mut() += 1;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
+  --> $DIR/reference_casting.rs:48:5
+   |
+LL |     *(std::ptr::from_ref({ num }) as *mut i32) += 1;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
+  --> $DIR/reference_casting.rs:51:5
    |
-LL |         let value = num as *const i32 as *mut i32;
-   |                     ----------------------------- casting happend here
-LL |         *value = 1;
-   |         ^^^^^^^^^^
+LL |     let value = num as *const i32 as *mut i32;
+   |                 ----------------------------- casting happend here
+LL |     *value = 1;
+   |     ^^^^^^^^^^
 
-error: aborting due to 9 previous errors
+error: aborting due to 14 previous errors