@@ -10,16 +10,6 @@ use rustc_middle::ty::{self, Ty, TyCtxt};
1010
1111pub struct AddRetag ;
1212
13- /// Determines whether this place is "stable": Whether, if we evaluate it again
14- /// after the assignment, we can be sure to obtain the same place value.
15- /// (Concurrent accesses by other threads are no problem as these are anyway non-atomic
16- /// copies. Data races are UB.)
17- fn is_stable ( place : PlaceRef < ' _ > ) -> bool {
18- // Which place this evaluates to can change with any memory write,
19- // so cannot assume deref to be stable.
20- !place. has_deref ( )
21- }
22-
2313/// Determine whether this type may contain a reference (or box), and thus needs retagging.
2414/// We will only recurse `depth` times into Tuples/ADTs to bound the cost of this.
2515fn may_contain_reference < ' tcx > ( ty : Ty < ' tcx > , depth : u32 , tcx : TyCtxt < ' tcx > ) -> bool {
@@ -69,22 +59,10 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
6959 let basic_blocks = body. basic_blocks . as_mut ( ) ;
7060 let local_decls = & body. local_decls ;
7161 let needs_retag = |place : & Place < ' tcx > | {
72- // FIXME: Instead of giving up for unstable places, we should introduce
73- // a temporary and retag on that.
74- is_stable ( place. as_ref ( ) )
62+ !place. has_deref ( ) // we're not eally interested in stores to "outside" locations, they are hard to keep track of anyway
7563 && may_contain_reference ( place. ty ( & * local_decls, tcx) . ty , /*depth*/ 3 , tcx)
7664 && !local_decls[ place. local ] . is_deref_temp ( )
7765 } ;
78- let place_base_raw = |place : & Place < ' tcx > | {
79- // If this is a `Deref`, get the type of what we are deref'ing.
80- if place. has_deref ( ) {
81- let ty = & local_decls[ place. local ] . ty ;
82- ty. is_unsafe_ptr ( )
83- } else {
84- // Not a deref, and thus not raw.
85- false
86- }
87- } ;
8866
8967 // PART 1
9068 // Retag arguments at the beginning of the start block.
@@ -108,7 +86,7 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
10886 }
10987
11088 // PART 2
111- // Retag return values of functions. Also escape-to-raw the argument of `drop`.
89+ // Retag return values of functions.
11290 // We collect the return destinations because we cannot mutate while iterating.
11391 let returns = basic_blocks
11492 . iter_mut ( )
@@ -140,30 +118,25 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
140118 }
141119
142120 // PART 3
143- // Add retag after assignment .
121+ // Add retag after assignments where data "enters" this function: the RHS is behind a deref and the LHS is not .
144122 for block_data in basic_blocks {
145123 // We want to insert statements as we iterate. To this end, we
146124 // iterate backwards using indices.
147125 for i in ( 0 ..block_data. statements . len ( ) ) . rev ( ) {
148126 let ( retag_kind, place) = match block_data. statements [ i] . kind {
149- // Retag-as-raw after escaping to a raw pointer, if the referent
150- // is not already a raw pointer.
151- StatementKind :: Assign ( box ( lplace, Rvalue :: AddressOf ( _, ref rplace) ) )
152- if !place_base_raw ( rplace) =>
153- {
154- ( RetagKind :: Raw , lplace)
155- }
156127 // Retag after assignments of reference type.
157128 StatementKind :: Assign ( box ( ref place, ref rvalue) ) if needs_retag ( place) => {
158- let kind = match rvalue {
159- Rvalue :: Ref ( _, borrow_kind, _)
160- if borrow_kind. allows_two_phase_borrow ( ) =>
161- {
162- RetagKind :: TwoPhase
163- }
164- _ => RetagKind :: Default ,
129+ let add_retag = match rvalue {
130+ // Ptr-creating operations already do their own internal retagging, no
131+ // need to also add a retag statement.
132+ Rvalue :: Ref ( ..) | Rvalue :: AddressOf ( ..) => false ,
133+ _ => true ,
165134 } ;
166- ( kind, * place)
135+ if add_retag {
136+ ( RetagKind :: Default , * place)
137+ } else {
138+ continue ;
139+ }
167140 }
168141 // Do nothing for the rest
169142 _ => continue ,
0 commit comments