about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs12
-rw-r--r--tests/ui/static/raw-ref-deref-without-unsafe.rs1
-rw-r--r--tests/ui/static/raw-ref-deref-without-unsafe.stderr2
-rw-r--r--tests/ui/unsafe/place-expr-safe.rs14
4 files changed, 18 insertions, 11 deletions
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index 8512763a595..0f0286fab29 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -512,17 +512,11 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                 // THIR desugars UNSAFE_STATIC into *UNSAFE_STATIC_REF, where
                 // UNSAFE_STATIC_REF holds the addr of the UNSAFE_STATIC, so: take two steps
                     && let ExprKind::Deref { arg } = self.thir[arg].kind
-                    // FIXME(workingjubiee): we lack a clear reason to reject ThreadLocalRef here,
-                    // but we also have no conclusive reason to allow it either!
-                    && let ExprKind::StaticRef { .. } = self.thir[arg].kind
                 {
-                    // A raw ref to a place expr, even an "unsafe static", is okay!
-                    // We short-circuit to not recursively traverse this expression.
+                    // Taking a raw ref to a deref place expr is always safe.
+                    // Make sure the expression we're deref'ing is safe, though.
+                    visit::walk_expr(self, &self.thir[arg]);
                     return;
-                    // note: const_mut_refs enables this code, and it currently remains unsafe:
-                    // static mut BYTE: u8 = 0;
-                    // static mut BYTE_PTR: *mut u8 = unsafe { addr_of_mut!(BYTE) };
-                    // static mut DEREF_BYTE_PTR: *mut u8 = unsafe { addr_of_mut!(*BYTE_PTR) };
                 }
             }
             ExprKind::Deref { arg } => {
diff --git a/tests/ui/static/raw-ref-deref-without-unsafe.rs b/tests/ui/static/raw-ref-deref-without-unsafe.rs
index 289e55b7638..7146c564e91 100644
--- a/tests/ui/static/raw-ref-deref-without-unsafe.rs
+++ b/tests/ui/static/raw-ref-deref-without-unsafe.rs
@@ -9,7 +9,6 @@ static mut BYTE_PTR: *mut u8 = ptr::addr_of_mut!(BYTE);
 // (it's fine to create raw refs to places!) the following derefs the ptr before creating its ref!
 static mut DEREF_BYTE_PTR: *mut u8 = ptr::addr_of_mut!(*BYTE_PTR);
 //~^ ERROR: use of mutable static
-//~| ERROR: dereference of raw pointer
 
 fn main() {
     let _ = unsafe { DEREF_BYTE_PTR };
diff --git a/tests/ui/static/raw-ref-deref-without-unsafe.stderr b/tests/ui/static/raw-ref-deref-without-unsafe.stderr
index f034499bbb5..d654d4b6e6b 100644
--- a/tests/ui/static/raw-ref-deref-without-unsafe.stderr
+++ b/tests/ui/static/raw-ref-deref-without-unsafe.stderr
@@ -14,6 +14,6 @@ LL | static mut DEREF_BYTE_PTR: *mut u8 = ptr::addr_of_mut!(*BYTE_PTR);
    |
    = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/unsafe/place-expr-safe.rs b/tests/ui/unsafe/place-expr-safe.rs
new file mode 100644
index 00000000000..2590ea74046
--- /dev/null
+++ b/tests/ui/unsafe/place-expr-safe.rs
@@ -0,0 +1,14 @@
+//@ check-pass
+
+fn main() {
+    let ptr = std::ptr::null_mut::<i32>();
+    let addr = &raw const *ptr;
+
+    let local = 1;
+    let ptr = &local as *const i32;
+    let addr = &raw const *ptr;
+
+    let boxed = Box::new(1);
+    let ptr = &*boxed as *const i32;
+    let addr = &raw const *ptr;
+}