Skip to content

Commit 6277c3a

Browse files
committed
Preserve unused pointer to address casts
1 parent 7fe2c4b commit 6277c3a

File tree

6 files changed

+65
-11
lines changed

6 files changed

+65
-11
lines changed

compiler/rustc_middle/src/mir/mod.rs

+27-2
Original file line numberDiff line numberDiff line change
@@ -2605,9 +2605,34 @@ pub enum Rvalue<'tcx> {
26052605
static_assert_size!(Rvalue<'_>, 40);
26062606

26072607
impl<'tcx> Rvalue<'tcx> {
2608+
/// Returns true if rvalue can be safely removed when the result is unused.
26082609
#[inline]
2609-
pub fn is_pointer_int_cast(&self) -> bool {
2610-
matches!(self, Rvalue::Cast(CastKind::PointerExposeAddress, _, _))
2610+
pub fn is_safe_to_remove(&self) -> bool {
2611+
match self {
2612+
// Pointer to int casts may be side-effects due to exposing the provenance.
2613+
// While the model is undecided, we should be conservative. See
2614+
// <https://www.ralfj.de/blog/2022/04/11/provenance-exposed.html>
2615+
Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => false,
2616+
2617+
Rvalue::Use(_)
2618+
| Rvalue::Repeat(_, _)
2619+
| Rvalue::Ref(_, _, _)
2620+
| Rvalue::ThreadLocalRef(_)
2621+
| Rvalue::AddressOf(_, _)
2622+
| Rvalue::Len(_)
2623+
| Rvalue::Cast(
2624+
CastKind::Misc | CastKind::Pointer(_) | CastKind::PointerFromExposedAddress,
2625+
_,
2626+
_,
2627+
)
2628+
| Rvalue::BinaryOp(_, _)
2629+
| Rvalue::CheckedBinaryOp(_, _)
2630+
| Rvalue::NullaryOp(_, _)
2631+
| Rvalue::UnaryOp(_, _)
2632+
| Rvalue::Discriminant(_)
2633+
| Rvalue::Aggregate(_, _)
2634+
| Rvalue::ShallowInitBox(_, _) => true,
2635+
}
26112636
}
26122637
}
26132638

compiler/rustc_mir_dataflow/src/impls/liveness.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -244,13 +244,10 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> {
244244
// Compute the place that we are storing to, if any
245245
let destination = match &statement.kind {
246246
StatementKind::Assign(assign) => {
247-
if assign.1.is_pointer_int_cast() {
248-
// Pointer to int casts may be side-effects due to exposing the provenance.
249-
// While the model is undecided, we should be conservative. See
250-
// <https://www.ralfj.de/blog/2022/04/11/provenance-exposed.html>
251-
None
252-
} else {
247+
if assign.1.is_safe_to_remove() {
253248
Some(assign.0)
249+
} else {
250+
None
254251
}
255252
}
256253
StatementKind::SetDiscriminant { place, .. } | StatementKind::Deinit(place) => {

compiler/rustc_mir_transform/src/dead_store_elimination.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, borrowed: &BitS
3434
for (statement_index, statement) in bb_data.statements.iter().enumerate().rev() {
3535
let loc = Location { block: bb, statement_index };
3636
if let StatementKind::Assign(assign) = &statement.kind {
37-
if assign.1.is_pointer_int_cast() {
37+
if !assign.1.is_safe_to_remove() {
3838
continue;
3939
}
4040
}

compiler/rustc_mir_transform/src/simplify.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -494,8 +494,12 @@ impl<'tcx> Visitor<'tcx> for UsedLocals {
494494
StatementKind::StorageLive(_local) | StatementKind::StorageDead(_local) => {}
495495

496496
StatementKind::Assign(box (ref place, ref rvalue)) => {
497-
self.visit_lhs(place, location);
498-
self.visit_rvalue(rvalue, location);
497+
if rvalue.is_safe_to_remove() {
498+
self.visit_lhs(place, location);
499+
self.visit_rvalue(rvalue, location);
500+
} else {
501+
self.super_statement(statement, location);
502+
}
499503
}
500504

501505
StatementKind::SetDiscriminant { ref place, variant_index: _ }

src/test/mir-opt/simplify-locals.rs

+7
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ fn t4() -> u32 {
6262
unsafe { X + 1 }
6363
}
6464

65+
// EMIT_MIR simplify_locals.expose_addr.SimplifyLocals.diff
66+
fn expose_addr(p: *const usize) {
67+
// Used pointer to address cast. Has a side effect of exposing the provenance.
68+
p as usize;
69+
}
70+
6571
fn main() {
6672
c();
6773
d1();
@@ -71,4 +77,5 @@ fn main() {
7177
t2();
7278
t3();
7379
t4();
80+
expose_addr(&0);
7481
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
- // MIR for `expose_addr` before SimplifyLocals
2+
+ // MIR for `expose_addr` after SimplifyLocals
3+
4+
fn expose_addr(_1: *const usize) -> () {
5+
debug p => _1; // in scope 0 at $DIR/simplify-locals.rs:66:16: 66:17
6+
let mut _0: (); // return place in scope 0 at $DIR/simplify-locals.rs:66:33: 66:33
7+
let _2: usize; // in scope 0 at $DIR/simplify-locals.rs:68:5: 68:15
8+
let mut _3: *const usize; // in scope 0 at $DIR/simplify-locals.rs:68:5: 68:6
9+
10+
bb0: {
11+
StorageLive(_2); // scope 0 at $DIR/simplify-locals.rs:68:5: 68:15
12+
StorageLive(_3); // scope 0 at $DIR/simplify-locals.rs:68:5: 68:6
13+
_3 = _1; // scope 0 at $DIR/simplify-locals.rs:68:5: 68:6
14+
_2 = move _3 as usize (PointerExposeAddress); // scope 0 at $DIR/simplify-locals.rs:68:5: 68:15
15+
StorageDead(_3); // scope 0 at $DIR/simplify-locals.rs:68:14: 68:15
16+
StorageDead(_2); // scope 0 at $DIR/simplify-locals.rs:68:15: 68:16
17+
_0 = const (); // scope 0 at $DIR/simplify-locals.rs:66:33: 69:2
18+
return; // scope 0 at $DIR/simplify-locals.rs:69:2: 69:2
19+
}
20+
}
21+

0 commit comments

Comments
 (0)