@@ -119,11 +119,6 @@ impl OptimizationFinder<'b, 'tcx> {
119
119
}
120
120
121
121
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
-
127
122
// Look for the sequence
128
123
//
129
124
// _2 = &_1;
@@ -137,6 +132,8 @@ impl OptimizationFinder<'b, 'tcx> {
137
132
_ => None ,
138
133
} ?;
139
134
135
+ let mut dead_locals_seen = vec ! [ ] ;
136
+
140
137
let stmt_index = location. statement_index ;
141
138
// Look behind for statement that assigns the local from a address of operator.
142
139
// 6 is chosen as a heuristic determined by seeing the number of times
@@ -160,6 +157,11 @@ impl OptimizationFinder<'b, 'tcx> {
160
157
BorrowKind :: Shared ,
161
158
place_taken_address_of,
162
159
) => {
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
+
163
165
self . optimizations
164
166
. unneeded_deref
165
167
. insert ( location, * place_taken_address_of) ;
@@ -178,13 +180,19 @@ impl OptimizationFinder<'b, 'tcx> {
178
180
// Inline asm can do anything, so bail out of the optimization.
179
181
rustc_middle:: mir:: StatementKind :: LlvmInlineAsm ( _) => return None ,
180
182
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
+
181
190
// Check that `local_being_deref` is not being used in a mutating way which can cause misoptimization.
182
191
rustc_middle:: mir:: StatementKind :: Assign ( box ( _, _) )
183
192
| rustc_middle:: mir:: StatementKind :: Coverage ( _)
184
193
| rustc_middle:: mir:: StatementKind :: Nop
185
194
| rustc_middle:: mir:: StatementKind :: FakeRead ( _, _)
186
195
| rustc_middle:: mir:: StatementKind :: StorageLive ( _)
187
- | rustc_middle:: mir:: StatementKind :: StorageDead ( _)
188
196
| rustc_middle:: mir:: StatementKind :: Retag ( _, _)
189
197
| rustc_middle:: mir:: StatementKind :: AscribeUserType ( _, _)
190
198
| rustc_middle:: mir:: StatementKind :: SetDiscriminant { .. } => {
0 commit comments