Skip to content

Commit c19620c

Browse files
committed
Do not apply the optimization if we deref a mutable ref
1 parent 2a71e45 commit c19620c

File tree

2 files changed

+49
-12
lines changed

2 files changed

+49
-12
lines changed

compiler/rustc_mir/src/transform/instcombine.rs

+32-12
Original file line numberDiff line numberDiff line change
@@ -167,10 +167,18 @@ impl OptimizationFinder<'b, 'tcx> {
167167
return None;
168168
}
169169

170-
self.optimizations
171-
.unneeded_deref
172-
.insert(location, *place_taken_address_of);
173-
return Some(());
170+
if place_derefs_non_mutable_ref(
171+
place_taken_address_of,
172+
self.body,
173+
self.tcx,
174+
) {
175+
self.optimizations
176+
.unneeded_deref
177+
.insert(location, *place_taken_address_of);
178+
return Some(());
179+
}
180+
181+
return None;
174182
}
175183

176184
// We found an assignment of `local_being_deref` that is not an immutable ref, e.g the following sequence
@@ -258,17 +266,29 @@ impl OptimizationFinder<'b, 'tcx> {
258266
}
259267
}
260268

269+
/// Returns whether this place derefences a type `&_`
270+
fn place_derefs_non_mutable_ref<'tcx>(
271+
place: &Place<'tcx>,
272+
body: &Body<'tcx>,
273+
tcx: TyCtxt<'tcx>,
274+
) -> bool {
275+
if let PlaceRef { local, projection: &[ref proj_base @ .., ProjectionElem::Deref] } =
276+
place.as_ref()
277+
{
278+
let ty = Place::ty_from(local, proj_base, body, tcx).ty;
279+
// The dereferenced place must have type `&_`.
280+
if let ty::Ref(_, _, Mutability::Not) = ty.kind() {
281+
return true;
282+
}
283+
}
284+
return false;
285+
}
286+
261287
impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> {
262288
fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
263289
if let Rvalue::Ref(_, _, place) = rvalue {
264-
if let PlaceRef { local, projection: &[ref proj_base @ .., ProjectionElem::Deref] } =
265-
place.as_ref()
266-
{
267-
// The dereferenced place must have type `&_`.
268-
let ty = Place::ty_from(local, proj_base, self.body, self.tcx).ty;
269-
if let ty::Ref(_, _, Mutability::Not) = ty.kind() {
270-
self.optimizations.and_stars.insert(location);
271-
}
290+
if place_derefs_non_mutable_ref(place, self.body, self.tcx) {
291+
self.optimizations.and_stars.insert(location);
272292
}
273293
}
274294

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

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// run-pass
2+
// compile-flags: -Z unsound_mir_opts
3+
4+
#[allow(unused_assignments)]
5+
fn main() {
6+
let a = 1u32;
7+
let b = 2u32;
8+
9+
let mut c: *const u32 = &a;
10+
let d: &u32 = &b;
11+
12+
let x = unsafe { &*c };
13+
c = d;
14+
let z = *x;
15+
16+
assert_eq!(1, z);
17+
}

0 commit comments

Comments
 (0)