Skip to content

Commit f27fdb5

Browse files
A raw ref of a deref is always safe
1 parent f04f6ca commit f27fdb5

File tree

4 files changed

+20
-19
lines changed

4 files changed

+20
-19
lines changed

compiler/rustc_mir_build/src/check_unsafety.rs

+3-9
Original file line numberDiff line numberDiff line change
@@ -503,17 +503,11 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
503503
// THIR desugars UNSAFE_STATIC into *UNSAFE_STATIC_REF, where
504504
// UNSAFE_STATIC_REF holds the addr of the UNSAFE_STATIC, so: take two steps
505505
&& let ExprKind::Deref { arg } = self.thir[arg].kind
506-
// FIXME(workingjubiee): we lack a clear reason to reject ThreadLocalRef here,
507-
// but we also have no conclusive reason to allow it either!
508-
&& let ExprKind::StaticRef { .. } = self.thir[arg].kind
509506
{
510-
// A raw ref to a place expr, even an "unsafe static", is okay!
511-
// We short-circuit to not recursively traverse this expression.
507+
// Taking a raw ref to a deref place expr is always safe.
508+
// Make sure the expression we're deref'ing is safe, though.
509+
visit::walk_expr(self, &self.thir[arg]);
512510
return;
513-
// note: const_mut_refs enables this code, and it currently remains unsafe:
514-
// static mut BYTE: u8 = 0;
515-
// static mut BYTE_PTR: *mut u8 = unsafe { addr_of_mut!(BYTE) };
516-
// static mut DEREF_BYTE_PTR: *mut u8 = unsafe { addr_of_mut!(*BYTE_PTR) };
517511
}
518512
}
519513
ExprKind::Deref { arg } => {

tests/ui/static/raw-ref-deref-without-unsafe.rs

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ static mut BYTE_PTR: *mut u8 = ptr::addr_of_mut!(BYTE);
1111
// (it's fine to create raw refs to places!) the following derefs the ptr before creating its ref!
1212
static mut DEREF_BYTE_PTR: *mut u8 = ptr::addr_of_mut!(*BYTE_PTR);
1313
//~^ ERROR: use of mutable static
14-
//~| ERROR: dereference of raw pointer
1514

1615
fn main() {
1716
let _ = unsafe { DEREF_BYTE_PTR };
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,3 @@
1-
error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block
2-
--> $DIR/raw-ref-deref-without-unsafe.rs:12:56
3-
|
4-
LL | static mut DEREF_BYTE_PTR: *mut u8 = ptr::addr_of_mut!(*BYTE_PTR);
5-
| ^^^^^^^^^ dereference of raw pointer
6-
|
7-
= note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
8-
91
error[E0133]: use of mutable static is unsafe and requires unsafe function or block
102
--> $DIR/raw-ref-deref-without-unsafe.rs:12:57
113
|
@@ -14,6 +6,6 @@ LL | static mut DEREF_BYTE_PTR: *mut u8 = ptr::addr_of_mut!(*BYTE_PTR);
146
|
157
= note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
168

17-
error: aborting due to 2 previous errors
9+
error: aborting due to 1 previous error
1810

1911
For more information about this error, try `rustc --explain E0133`.

tests/ui/unsafe/place-expr-safe.rs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#![feature(raw_ref_op)]
2+
3+
//@ check-pass
4+
5+
fn main() {
6+
let ptr = std::ptr::null_mut::<i32>();
7+
let addr = &raw const *ptr;
8+
9+
let local = 1;
10+
let ptr = &local as *const i32;
11+
let addr = &raw const *ptr;
12+
13+
let boxed = Box::new(1);
14+
let ptr = &*boxed as *const i32;
15+
let addr = &raw const *ptr;
16+
}

0 commit comments

Comments
 (0)