summary refs log tree commit diff
path: root/compiler/rustc_mir_transform/src
diff options
context:
space:
mode:
authorJannis Christopher Köhl <mail@koehl.dev>2022-09-01 14:17:15 +0200
committerJannis Christopher Köhl <mail@koehl.dev>2022-11-07 10:35:11 +0100
commitad99d2e15dd9f36a1b84359f8b9bb9ffbaa5ac60 (patch)
tree4083d3b89a3fd0c92fcf6bb1fbb6b79b7ce65d8c /compiler/rustc_mir_transform/src
parent3f98dc78380a60ffea0e5849393a718a10f495b4 (diff)
downloadrust-ad99d2e15dd9f36a1b84359f8b9bb9ffbaa5ac60.tar.gz
rust-ad99d2e15dd9f36a1b84359f8b9bb9ffbaa5ac60.zip
Move handling of references and simplify flooding
Diffstat (limited to 'compiler/rustc_mir_transform/src')
-rw-r--r--compiler/rustc_mir_transform/src/dataflow_const_prop.rs34
1 files changed, 21 insertions, 13 deletions
diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
index f1220f634ac..b05b0fdfd43 100644
--- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
+++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
@@ -3,7 +3,9 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_middle::mir::visit::{MutVisitor, Visitor};
 use rustc_middle::mir::*;
 use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt};
-use rustc_mir_dataflow::value_analysis::{Map, ProjElem, State, ValueAnalysis, ValueOrPlace};
+use rustc_mir_dataflow::value_analysis::{
+    Map, ProjElem, State, ValueAnalysis, ValueOrPlace, ValueOrPlaceOrRef,
+};
 use rustc_mir_dataflow::{lattice::FlatSet, Analysis, ResultsVisitor, SwitchIntEdgeEffects};
 use rustc_span::DUMMY_SP;
 
@@ -59,6 +61,12 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'tcx> {
         match rvalue {
             Rvalue::CheckedBinaryOp(op, box (left, right)) => {
                 let target = self.map().find(target.as_ref());
+                if let Some(target) = target {
+                    // We should not track any projections other than
+                    // what is overwritten below, but just in case...
+                    state.flood_idx(target, self.map());
+                }
+
                 let value_target = target.and_then(|target| {
                     self.map().apply_elem(target, ProjElem::Field(0_u32.into()))
                 });
@@ -70,12 +78,12 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'tcx> {
                     let (val, overflow) = self.binary_op(state, *op, left, right);
 
                     if let Some(value_target) = value_target {
-                        state.assign_idx(value_target, ValueOrPlace::Value(val), self.map());
+                        state.assign_idx(value_target, ValueOrPlaceOrRef::Value(val), self.map());
                     }
                     if let Some(overflow_target) = overflow_target {
                         state.assign_idx(
                             overflow_target,
-                            ValueOrPlace::Value(overflow),
+                            ValueOrPlaceOrRef::Value(overflow),
                             self.map(),
                         );
                     }
@@ -89,7 +97,7 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'tcx> {
         &self,
         rvalue: &Rvalue<'tcx>,
         state: &mut State<Self::Value>,
-    ) -> ValueOrPlace<Self::Value> {
+    ) -> ValueOrPlaceOrRef<Self::Value> {
         match rvalue {
             Rvalue::Cast(CastKind::Misc, operand, ty) => {
                 let operand = self.eval_operand(operand, state);
@@ -97,24 +105,24 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'tcx> {
                     FlatSet::Elem(operand) => self
                         .ecx
                         .misc_cast(&operand, *ty)
-                        .map(|result| ValueOrPlace::Value(self.wrap_immediate(result, *ty)))
-                        .unwrap_or(ValueOrPlace::Unknown),
-                    _ => ValueOrPlace::Unknown,
+                        .map(|result| ValueOrPlaceOrRef::Value(self.wrap_immediate(result, *ty)))
+                        .unwrap_or(ValueOrPlaceOrRef::Unknown),
+                    _ => ValueOrPlaceOrRef::Unknown,
                 }
             }
             Rvalue::BinaryOp(op, box (left, right)) => {
                 let (val, _overflow) = self.binary_op(state, *op, left, right);
                 // FIXME: Just ignore overflow here?
-                ValueOrPlace::Value(val)
+                ValueOrPlaceOrRef::Value(val)
             }
             Rvalue::UnaryOp(op, operand) => match self.eval_operand(operand, state) {
                 FlatSet::Elem(value) => self
                     .ecx
                     .unary_op(*op, &value)
-                    .map(|val| ValueOrPlace::Value(self.wrap_immty(val)))
-                    .unwrap_or(ValueOrPlace::Value(FlatSet::Top)),
-                FlatSet::Bottom => ValueOrPlace::Value(FlatSet::Bottom),
-                FlatSet::Top => ValueOrPlace::Value(FlatSet::Top),
+                    .map(|val| ValueOrPlaceOrRef::Value(self.wrap_immty(val)))
+                    .unwrap_or(ValueOrPlaceOrRef::Value(FlatSet::Top)),
+                FlatSet::Bottom => ValueOrPlaceOrRef::Value(FlatSet::Bottom),
+                FlatSet::Top => ValueOrPlaceOrRef::Value(FlatSet::Top),
             },
             _ => self.super_rvalue(rvalue, state),
         }
@@ -175,7 +183,7 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'tcx> {
                 handled = true;
             } else {
                 // Branch is not taken, we can flood everything.
-                state.flood_all(FlatSet::Bottom);
+                state.flood_all();
             }
         })
     }