about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCamille GILLOT <gillot.camille@gmail.com>2023-01-30 17:37:56 +0000
committerCamille GILLOT <gillot.camille@gmail.com>2023-02-06 22:01:07 +0000
commit67a8c16fe285dc5dc3ca8a0c74fb1bcfa58ce8dc (patch)
tree7fba5ca12c864fecfe89e8c47564dda981605f87
parent9af191f86f2c81ec5613ae35ab1a3b2ac3edbdee (diff)
downloadrust-67a8c16fe285dc5dc3ca8a0c74fb1bcfa58ce8dc.tar.gz
rust-67a8c16fe285dc5dc3ca8a0c74fb1bcfa58ce8dc.zip
Complete for_each_aliasing_place.
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs8
-rw-r--r--compiler/rustc_mir_dataflow/src/value_analysis.rs7
2 files changed, 15 insertions, 0 deletions
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 10ac7e0d39a..e272c90e0cd 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -1640,6 +1640,14 @@ impl<'tcx> PlaceRef<'tcx> {
         }
     }
 
+    /// Returns `true` if this `Place` contains a `Deref` projection.
+    ///
+    /// If `Place::is_indirect` returns false, the caller knows that the `Place` refers to the
+    /// same region of memory as its base.
+    pub fn is_indirect(&self) -> bool {
+        self.projection.iter().any(|elem| elem.is_indirect())
+    }
+
     /// If MirPhase >= Derefered and if projection contains Deref,
     /// It's guaranteed to be in the first place
     pub fn has_deref(&self) -> bool {
diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs
index 353b8d801d5..f24280e2187 100644
--- a/compiler/rustc_mir_dataflow/src/value_analysis.rs
+++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs
@@ -780,6 +780,10 @@ impl Map {
         tail_elem: Option<TrackElem>,
         f: &mut impl FnMut(PlaceIndex),
     ) {
+        if place.is_indirect() {
+            // We do not track indirect places.
+            return;
+        }
         let Some(&Some(mut index)) = self.locals.get(place.local) else {
             // The local is not tracked at all, so it does not alias anything.
             return;
@@ -790,6 +794,9 @@ impl Map {
             .map(|&elem| elem.try_into())
             .chain(tail_elem.map(Ok).into_iter());
         for elem in elems {
+            // A field aliases the parent place.
+            f(index);
+
             let Ok(elem) = elem else { return };
             let sub = self.apply(index, elem);
             if let TrackElem::Variant(..) | TrackElem::Discriminant = elem {