about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-08-17 11:49:21 +0000
committerbors <bors@rust-lang.org>2023-08-17 11:49:21 +0000
commit23b9d9558ce3e5974df162c8ec7cc8e46c99072d (patch)
treed8af49796f77955a12b7cdffe0b3a28931f10191
parent6249c70dbb12d12b55f77b64fb0e71ac6c9ec806 (diff)
parentf836cfa69347ba27097a510d689eb7041ea63d2b (diff)
downloadrust-23b9d9558ce3e5974df162c8ec7cc8e46c99072d.tar.gz
rust-23b9d9558ce3e5974df162c8ec7cc8e46c99072d.zip
Auto merge of #3031 - RalfJung:foreign-read, r=RalfJung
tree borrows: more comments in foreign_read transition
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs20
1 files changed, 17 insertions, 3 deletions
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs
index 0ce29ac5437..dab216bc5b1 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs
@@ -68,17 +68,31 @@ mod transition {
     fn foreign_read(state: PermissionPriv, protected: bool) -> Option<PermissionPriv> {
         use Option::*;
         Some(match state {
+            // Non-writeable states just ignore foreign reads.
+            non_writeable @ (Frozen | Disabled) => non_writeable,
+            // Writeable states are more tricky, and depend on whether things are protected.
             // The inner data `ty_is_freeze` of `Reserved` is always irrelevant for Read
             // accesses, since the data is not being mutated. Hence the `{ .. }`
-            res @ Reserved { .. } if !protected => res,
-            Reserved { .. } => Frozen, // protected reserved
+            res @ Reserved { .. } =>
+                if protected {
+                    // Someone else read, make sure we won't write.
+                    // We could make this `Disabled` but it doesn't look like we get anything out of that extra UB.
+                    Frozen
+                } else {
+                    // Before activation and without protectors, foreign reads are fine.
+                    // That's the entire point of 2-phase borrows.
+                    res
+                },
             Active =>
                 if protected {
+                    // We wrote, someone else reads -- that's bad.
+                    // (If this is initialized, this move-to-protected will mean insta-UB.)
                     Disabled
                 } else {
+                    // We don't want to disable here to allow read-read reordering: it is crucial
+                    // that the foreign read does not invalidate future reads through this tag.
                     Frozen
                 },
-            non_writeable @ (Frozen | Disabled) => non_writeable,
         })
     }