diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index 662ab0bdfa5..a4ade54604e 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -339,7 +339,9 @@ impl State { pub fn assign_idx(&mut self, target: PlaceIndex, result: ValueOrPlace, map: &Map) { match result { ValueOrPlace::Value(value) => { - // FIXME: What if not all tracked projections are overwritten? Can this happen? + // First flood the target place in case we also track any projections (although + // this scenario is currently not well-supported with the ValueOrPlace interface). + self.flood_idx(target, map, V::top()); if let Some(value_index) = map.places[target].value_index { self.0[value_index] = value; } diff --git a/src/test/mir-opt/dataflow-const-prop/static_ref.main.DataflowConstProp.diff b/src/test/mir-opt/dataflow-const-prop/static_ref.main.DataflowConstProp.diff new file mode 100644 index 00000000000..4c6c0bd8f3e --- /dev/null +++ b/src/test/mir-opt/dataflow-const-prop/static_ref.main.DataflowConstProp.diff @@ -0,0 +1,53 @@ +- // MIR for `main` before DataflowConstProp ++ // MIR for `main` after DataflowConstProp + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/static_ref.rs:+0:11: +0:11 + let _1: usize; // in scope 0 at $DIR/static_ref.rs:+2:9: +2:10 + let mut _3: &usize; // in scope 0 at $DIR/static_ref.rs:+4:9: +4:11 + let _4: &usize; // in scope 0 at $DIR/static_ref.rs:+4:9: +4:11 + let _5: &usize; // in scope 0 at $DIR/static_ref.rs:+4:10: +4:11 + scope 1 { + debug x => _1; // in scope 1 at $DIR/static_ref.rs:+2:9: +2:10 + let mut _2: &usize; // in scope 1 at $DIR/static_ref.rs:+3:9: +3:14 + scope 2 { + debug r => _2; // in scope 2 at $DIR/static_ref.rs:+3:9: +3:14 + let _6: usize; // in scope 2 at $DIR/static_ref.rs:+5:9: +5:10 + scope 3 { + debug y => _6; // in scope 3 at $DIR/static_ref.rs:+5:9: +5:10 + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/static_ref.rs:+2:9: +2:10 + _1 = const 0_usize; // scope 0 at $DIR/static_ref.rs:+2:13: +2:14 + StorageLive(_2); // scope 1 at $DIR/static_ref.rs:+3:9: +3:14 + _2 = &_1; // scope 1 at $DIR/static_ref.rs:+3:17: +3:19 + StorageLive(_3); // scope 2 at $DIR/static_ref.rs:+4:9: +4:11 + StorageLive(_4); // scope 2 at $DIR/static_ref.rs:+4:9: +4:11 + StorageLive(_5); // scope 2 at $DIR/static_ref.rs:+4:10: +4:11 + _5 = const {alloc1: &usize}; // scope 2 at $DIR/static_ref.rs:+4:10: +4:11 + // mir::Constant + // + span: $DIR/static_ref.rs:8:10: 8:11 + // + literal: Const { ty: &usize, val: Value(Scalar(alloc1)) } + _4 = &(*_5); // scope 2 at $DIR/static_ref.rs:+4:9: +4:11 + _3 = &(*_4); // scope 2 at $DIR/static_ref.rs:+4:9: +4:11 + _2 = move _3; // scope 2 at $DIR/static_ref.rs:+4:5: +4:11 + StorageDead(_3); // scope 2 at $DIR/static_ref.rs:+4:10: +4:11 + StorageDead(_5); // scope 2 at $DIR/static_ref.rs:+4:11: +4:12 + StorageDead(_4); // scope 2 at $DIR/static_ref.rs:+4:11: +4:12 + StorageLive(_6); // scope 2 at $DIR/static_ref.rs:+5:9: +5:10 + _6 = (*_2); // scope 2 at $DIR/static_ref.rs:+5:13: +5:15 + _0 = const (); // scope 0 at $DIR/static_ref.rs:+0:11: +6:2 + StorageDead(_6); // scope 2 at $DIR/static_ref.rs:+6:1: +6:2 + StorageDead(_2); // scope 1 at $DIR/static_ref.rs:+6:1: +6:2 + StorageDead(_1); // scope 0 at $DIR/static_ref.rs:+6:1: +6:2 + return; // scope 0 at $DIR/static_ref.rs:+6:2: +6:2 + } + } + + alloc1 (static: P, size: 8, align: 8) { + 05 00 00 00 00 00 00 00 │ ........ + } + diff --git a/src/test/mir-opt/dataflow-const-prop/static_ref.rs b/src/test/mir-opt/dataflow-const-prop/static_ref.rs new file mode 100644 index 00000000000..d5e8063cf01 --- /dev/null +++ b/src/test/mir-opt/dataflow-const-prop/static_ref.rs @@ -0,0 +1,10 @@ +// unit-test: DataflowConstProp + +// EMIT_MIR static_ref.main.DataflowConstProp.diff +fn main() { + static P: usize = 5; + let x = 0; + let mut r = &x; + r = &P; + let y = *r; +}