Skip to content

Commit 8646c2a

Browse files
authored
Rollup merge of #78247 - simonvandel:fix-78192, r=oli-obk
Fix #78192 Check which places are marked dead. Fixes #78192
2 parents 083a5cd + 57d01a9 commit 8646c2a

File tree

6 files changed

+55
-9
lines changed

6 files changed

+55
-9
lines changed

compiler/rustc_mir/src/transform/instcombine.rs

+14-6
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,6 @@ impl OptimizationFinder<'b, 'tcx> {
119119
}
120120

121121
fn find_deref_of_address(&mut self, rvalue: &Rvalue<'tcx>, location: Location) -> Option<()> {
122-
// FIXME(#78192): This optimization can result in unsoundness.
123-
if !self.tcx.sess.opts.debugging_opts.unsound_mir_opts {
124-
return None;
125-
}
126-
127122
// Look for the sequence
128123
//
129124
// _2 = &_1;
@@ -137,6 +132,8 @@ impl OptimizationFinder<'b, 'tcx> {
137132
_ => None,
138133
}?;
139134

135+
let mut dead_locals_seen = vec![];
136+
140137
let stmt_index = location.statement_index;
141138
// Look behind for statement that assigns the local from a address of operator.
142139
// 6 is chosen as a heuristic determined by seeing the number of times
@@ -160,6 +157,11 @@ impl OptimizationFinder<'b, 'tcx> {
160157
BorrowKind::Shared,
161158
place_taken_address_of,
162159
) => {
160+
// Make sure that the place has not been marked dead
161+
if dead_locals_seen.contains(&place_taken_address_of.local) {
162+
return None;
163+
}
164+
163165
self.optimizations
164166
.unneeded_deref
165167
.insert(location, *place_taken_address_of);
@@ -178,13 +180,19 @@ impl OptimizationFinder<'b, 'tcx> {
178180
// Inline asm can do anything, so bail out of the optimization.
179181
rustc_middle::mir::StatementKind::LlvmInlineAsm(_) => return None,
180182

183+
// Remember `StorageDead`s, as the local being marked dead could be the
184+
// place RHS we are looking for, in which case we need to abort to avoid UB
185+
// using an uninitialized place
186+
rustc_middle::mir::StatementKind::StorageDead(dead) => {
187+
dead_locals_seen.push(*dead)
188+
}
189+
181190
// Check that `local_being_deref` is not being used in a mutating way which can cause misoptimization.
182191
rustc_middle::mir::StatementKind::Assign(box (_, _))
183192
| rustc_middle::mir::StatementKind::Coverage(_)
184193
| rustc_middle::mir::StatementKind::Nop
185194
| rustc_middle::mir::StatementKind::FakeRead(_, _)
186195
| rustc_middle::mir::StatementKind::StorageLive(_)
187-
| rustc_middle::mir::StatementKind::StorageDead(_)
188196
| rustc_middle::mir::StatementKind::Retag(_, _)
189197
| rustc_middle::mir::StatementKind::AscribeUserType(_, _)
190198
| rustc_middle::mir::StatementKind::SetDiscriminant { .. } => {

src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
// + span: $DIR/ref_deref.rs:5:6: 5:10
2020
// + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
2121
_2 = _4; // scope 0 at $DIR/ref_deref.rs:5:6: 5:10
22-
- _1 = (*_2); // scope 0 at $DIR/ref_deref.rs:5:5: 5:10
22+
- _1 = (*_4); // scope 0 at $DIR/ref_deref.rs:5:5: 5:10
2323
+ _1 = const 4_i32; // scope 0 at $DIR/ref_deref.rs:5:5: 5:10
2424
StorageDead(_2); // scope 0 at $DIR/ref_deref.rs:5:10: 5:11
2525
StorageDead(_1); // scope 0 at $DIR/ref_deref.rs:5:10: 5:11

src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
// + span: $DIR/ref_deref_project.rs:5:6: 5:17
2020
// + literal: Const { ty: &(i32, i32), val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
2121
_2 = &((*_4).1: i32); // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17
22-
_1 = (*_2); // scope 0 at $DIR/ref_deref_project.rs:5:5: 5:17
22+
_1 = ((*_4).1: i32); // scope 0 at $DIR/ref_deref_project.rs:5:5: 5:17
2323
StorageDead(_2); // scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18
2424
StorageDead(_1); // scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18
2525
_0 = const (); // scope 0 at $DIR/ref_deref_project.rs:4:11: 6:2

src/test/mir-opt/inst_combine_deref.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// compile-flags: -O -Zunsound-mir-opts
1+
// compile-flags: -O
22
// EMIT_MIR inst_combine_deref.simple_opt.InstCombine.diff
33
fn simple_opt() -> u64 {
44
let x = 5;

src/test/mir-opt/issue-78192.rs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// EMIT_MIR issue_78192.f.InstCombine.diff
2+
pub fn f<T>(a: &T) -> *const T {
3+
let b: &*const T = &(a as *const T);
4+
*b
5+
}
6+
7+
fn main() {
8+
f(&2);
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
- // MIR for `f` before InstCombine
2+
+ // MIR for `f` after InstCombine
3+
4+
fn f(_1: &T) -> *const T {
5+
debug a => _1; // in scope 0 at $DIR/issue-78192.rs:2:13: 2:14
6+
let mut _0: *const T; // return place in scope 0 at $DIR/issue-78192.rs:2:23: 2:31
7+
let _2: &*const T; // in scope 0 at $DIR/issue-78192.rs:3:9: 3:10
8+
let _3: &*const T; // in scope 0 at $DIR/issue-78192.rs:3:24: 3:40
9+
let _4: *const T; // in scope 0 at $DIR/issue-78192.rs:3:25: 3:40
10+
scope 1 {
11+
debug b => _2; // in scope 1 at $DIR/issue-78192.rs:3:9: 3:10
12+
}
13+
14+
bb0: {
15+
StorageLive(_2); // scope 0 at $DIR/issue-78192.rs:3:9: 3:10
16+
StorageLive(_3); // scope 0 at $DIR/issue-78192.rs:3:24: 3:40
17+
StorageLive(_4); // scope 0 at $DIR/issue-78192.rs:3:25: 3:40
18+
_4 = &raw const (*_1); // scope 0 at $DIR/issue-78192.rs:3:26: 3:27
19+
_3 = &_4; // scope 0 at $DIR/issue-78192.rs:3:24: 3:40
20+
- _2 = &(*_3); // scope 0 at $DIR/issue-78192.rs:3:24: 3:40
21+
+ _2 = _3; // scope 0 at $DIR/issue-78192.rs:3:24: 3:40
22+
StorageDead(_3); // scope 0 at $DIR/issue-78192.rs:3:40: 3:41
23+
_0 = (*_2); // scope 1 at $DIR/issue-78192.rs:4:5: 4:7
24+
StorageDead(_4); // scope 0 at $DIR/issue-78192.rs:5:1: 5:2
25+
StorageDead(_2); // scope 0 at $DIR/issue-78192.rs:5:1: 5:2
26+
return; // scope 0 at $DIR/issue-78192.rs:5:2: 5:2
27+
}
28+
}
29+

0 commit comments

Comments
 (0)