Skip to content

Commit 18d4e22

Browse files
authored
Rollup merge of #110954 - cjgillot:const-prop-ref, r=wesleywiser
Reject borrows of projections in ConstProp. Fixes #110947
2 parents d98e174 + 1ffe905 commit 18d4e22

File tree

5 files changed

+80
-9
lines changed

5 files changed

+80
-9
lines changed

compiler/rustc_mir_transform/src/const_prop.rs

+15-5
Original file line numberDiff line numberDiff line change
@@ -714,13 +714,22 @@ impl CanConstProp {
714714
}
715715
}
716716

717-
impl Visitor<'_> for CanConstProp {
717+
impl<'tcx> Visitor<'tcx> for CanConstProp {
718+
fn visit_place(&mut self, place: &Place<'tcx>, mut context: PlaceContext, loc: Location) {
719+
use rustc_middle::mir::visit::PlaceContext::*;
720+
721+
// Dereferencing just read the addess of `place.local`.
722+
if place.projection.first() == Some(&PlaceElem::Deref) {
723+
context = NonMutatingUse(NonMutatingUseContext::Copy);
724+
}
725+
726+
self.visit_local(place.local, context, loc);
727+
self.visit_projection(place.as_ref(), context, loc);
728+
}
729+
718730
fn visit_local(&mut self, local: Local, context: PlaceContext, _: Location) {
719731
use rustc_middle::mir::visit::PlaceContext::*;
720732
match context {
721-
// Projections are fine, because `&mut foo.x` will be caught by
722-
// `MutatingUseContext::Borrow` elsewhere.
723-
MutatingUse(MutatingUseContext::Projection)
724733
// These are just stores, where the storing is not propagatable, but there may be later
725734
// mutations of the same local via `Store`
726735
| MutatingUse(MutatingUseContext::Call)
@@ -751,7 +760,6 @@ impl Visitor<'_> for CanConstProp {
751760
NonMutatingUse(NonMutatingUseContext::Copy)
752761
| NonMutatingUse(NonMutatingUseContext::Move)
753762
| NonMutatingUse(NonMutatingUseContext::Inspect)
754-
| NonMutatingUse(NonMutatingUseContext::Projection)
755763
| NonMutatingUse(NonMutatingUseContext::PlaceMention)
756764
| NonUse(_) => {}
757765

@@ -771,6 +779,8 @@ impl Visitor<'_> for CanConstProp {
771779
trace!("local {:?} can't be propagated because it's used: {:?}", local, context);
772780
self.can_const_prop[local] = ConstPropMode::NoPropagation;
773781
}
782+
MutatingUse(MutatingUseContext::Projection)
783+
| NonMutatingUse(NonMutatingUseContext::Projection) => bug!("visit_place should not pass {context:?} for {local:?}"),
774784
}
775785
}
776786
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
- // MIR for `fn0` before ConstProp
2+
+ // MIR for `fn0` after ConstProp
3+
4+
fn fn0() -> bool {
5+
let mut _0: bool; // return place in scope 0 at $DIR/address_of_pair.rs:+0:17: +0:21
6+
let mut _1: !; // in scope 0 at $DIR/address_of_pair.rs:+0:22: +9:2
7+
let mut _2: (i32, bool); // in scope 0 at $DIR/address_of_pair.rs:+1:9: +1:17
8+
let _4: (); // in scope 0 at $DIR/address_of_pair.rs:+4:5: +6:6
9+
let mut _6: bool; // in scope 0 at $DIR/address_of_pair.rs:+7:16: +7:22
10+
scope 1 {
11+
debug pair => _2; // in scope 1 at $DIR/address_of_pair.rs:+1:9: +1:17
12+
let _3: *mut bool; // in scope 1 at $DIR/address_of_pair.rs:+2:9: +2:12
13+
scope 2 {
14+
debug ptr => _3; // in scope 2 at $DIR/address_of_pair.rs:+2:9: +2:12
15+
let _5: bool; // in scope 2 at $DIR/address_of_pair.rs:+7:9: +7:12
16+
scope 3 {
17+
}
18+
scope 4 {
19+
debug ret => _5; // in scope 4 at $DIR/address_of_pair.rs:+7:9: +7:12
20+
}
21+
}
22+
}
23+
24+
bb0: {
25+
StorageLive(_2); // scope 0 at $DIR/address_of_pair.rs:+1:9: +1:17
26+
_2 = (const 1_i32, const false); // scope 0 at $DIR/address_of_pair.rs:+1:20: +1:30
27+
StorageLive(_3); // scope 1 at $DIR/address_of_pair.rs:+2:9: +2:12
28+
_3 = &raw mut (_2.1: bool); // scope 1 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
29+
_2 = (const 1_i32, const false); // scope 2 at $DIR/address_of_pair.rs:+3:5: +3:22
30+
StorageLive(_4); // scope 2 at $DIR/address_of_pair.rs:+4:5: +6:6
31+
(*_3) = const true; // scope 3 at $DIR/address_of_pair.rs:+5:9: +5:20
32+
_4 = const (); // scope 3 at $DIR/address_of_pair.rs:+4:5: +6:6
33+
StorageDead(_4); // scope 2 at $DIR/address_of_pair.rs:+6:5: +6:6
34+
StorageLive(_5); // scope 2 at $DIR/address_of_pair.rs:+7:9: +7:12
35+
StorageLive(_6); // scope 2 at $DIR/address_of_pair.rs:+7:16: +7:22
36+
_6 = (_2.1: bool); // scope 2 at $DIR/address_of_pair.rs:+7:16: +7:22
37+
_5 = Not(move _6); // scope 2 at $DIR/address_of_pair.rs:+7:15: +7:22
38+
StorageDead(_6); // scope 2 at $DIR/address_of_pair.rs:+7:21: +7:22
39+
_0 = _5; // scope 4 at $DIR/address_of_pair.rs:+8:12: +8:15
40+
StorageDead(_5); // scope 2 at $DIR/address_of_pair.rs:+9:1: +9:2
41+
StorageDead(_3); // scope 1 at $DIR/address_of_pair.rs:+9:1: +9:2
42+
StorageDead(_2); // scope 0 at $DIR/address_of_pair.rs:+9:1: +9:2
43+
return; // scope 0 at $DIR/address_of_pair.rs:+9:2: +9:2
44+
}
45+
}
46+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// unit-test: ConstProp
2+
3+
// EMIT_MIR address_of_pair.fn0.ConstProp.diff
4+
pub fn fn0() -> bool {
5+
let mut pair = (1, false);
6+
let ptr = core::ptr::addr_of_mut!(pair.1);
7+
pair = (1, false);
8+
unsafe {
9+
*ptr = true;
10+
}
11+
let ret = !pair.1;
12+
return ret;
13+
}
14+
15+
pub fn main() {
16+
println!("{}", fn0());
17+
}

tests/mir-opt/const_prop_miscompile.bar.ConstProp.diff

+1-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@
1919

2020
bb0: {
2121
StorageLive(_1); // scope 0 at $DIR/const_prop_miscompile.rs:+1:9: +1:14
22-
- _1 = (const 1_i32,); // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21
23-
+ _1 = const (1_i32,); // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21
22+
_1 = (const 1_i32,); // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21
2423
StorageLive(_2); // scope 1 at $DIR/const_prop_miscompile.rs:+2:5: +4:6
2524
StorageLive(_3); // scope 2 at $DIR/const_prop_miscompile.rs:+3:10: +3:22
2625
_3 = &raw mut (_1.0: i32); // scope 2 at $DIR/const_prop_miscompile.rs:+3:10: +3:22

tests/mir-opt/const_prop_miscompile.foo.ConstProp.diff

+1-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@
1616

1717
bb0: {
1818
StorageLive(_1); // scope 0 at $DIR/const_prop_miscompile.rs:+1:9: +1:14
19-
- _1 = (const 1_i32,); // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21
20-
+ _1 = const (1_i32,); // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21
19+
_1 = (const 1_i32,); // scope 0 at $DIR/const_prop_miscompile.rs:+1:17: +1:21
2120
StorageLive(_2); // scope 1 at $DIR/const_prop_miscompile.rs:+2:6: +2:14
2221
_2 = &mut (_1.0: i32); // scope 1 at $DIR/const_prop_miscompile.rs:+2:6: +2:14
2322
(*_2) = const 5_i32; // scope 1 at $DIR/const_prop_miscompile.rs:+2:5: +2:18

0 commit comments

Comments
 (0)