@@ -5,11 +5,12 @@ use rustc_middle::mir::{BorrowKind, Mutability, Operand};
5
5
use rustc_middle:: mir:: { InlineAsmOperand , Terminator , TerminatorKind } ;
6
6
use rustc_middle:: mir:: { Statement , StatementKind } ;
7
7
use rustc_middle:: ty:: TyCtxt ;
8
+ use std:: iter;
8
9
9
10
use crate :: {
10
11
borrow_set:: BorrowSet , facts:: AllFacts , location:: LocationTable , path_utils:: * , AccessDepth ,
11
- Activation , ArtificialField , BorrowIndex , Deep , LocalMutationIsAllowed , Read , ReadKind ,
12
- ReadOrWrite , Reservation , Shallow , Write , WriteKind ,
12
+ Activation , ArtificialField , BorrowIndex , Deep , JustWrite , LocalMutationIsAllowed , MutateMode ,
13
+ Read , ReadKind , ReadOrWrite , Reservation , Shallow , Write , WriteAndRead , WriteKind ,
13
14
} ;
14
15
15
16
pub ( super ) fn generate_invalidates < ' tcx > (
@@ -58,13 +59,37 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
58
59
StatementKind :: Assign ( box ( lhs, rhs) ) => {
59
60
self . consume_rvalue ( location, rhs) ;
60
61
61
- self . mutate_place ( location, * lhs, Shallow ( None ) ) ;
62
+ self . mutate_place ( location, * lhs, Shallow ( None ) , JustWrite ) ;
62
63
}
63
64
StatementKind :: FakeRead ( box ( _, _) ) => {
64
65
// Only relevant for initialized/liveness/safety checks.
65
66
}
66
67
StatementKind :: SetDiscriminant { place, variant_index : _ } => {
67
- self . mutate_place ( location, * * place, Shallow ( None ) ) ;
68
+ self . mutate_place ( location, * * place, Shallow ( None ) , JustWrite ) ;
69
+ }
70
+ StatementKind :: LlvmInlineAsm ( asm) => {
71
+ for ( o, output) in iter:: zip ( & asm. asm . outputs , & * asm. outputs ) {
72
+ if o. is_indirect {
73
+ // FIXME(eddyb) indirect inline asm outputs should
74
+ // be encoded through MIR place derefs instead.
75
+ self . access_place (
76
+ location,
77
+ * output,
78
+ ( Deep , Read ( ReadKind :: Copy ) ) ,
79
+ LocalMutationIsAllowed :: No ,
80
+ ) ;
81
+ } else {
82
+ self . mutate_place (
83
+ location,
84
+ * output,
85
+ if o. is_rw { Deep } else { Shallow ( None ) } ,
86
+ if o. is_rw { WriteAndRead } else { JustWrite } ,
87
+ ) ;
88
+ }
89
+ }
90
+ for ( _, input) in asm. inputs . iter ( ) {
91
+ self . consume_operand ( location, input) ;
92
+ }
68
93
}
69
94
StatementKind :: CopyNonOverlapping ( box rustc_middle:: mir:: CopyNonOverlapping {
70
95
ref src,
@@ -117,7 +142,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
117
142
target : _,
118
143
unwind : _,
119
144
} => {
120
- self . mutate_place ( location, * drop_place, Deep ) ;
145
+ self . mutate_place ( location, * drop_place, Deep , JustWrite ) ;
121
146
self . consume_operand ( location, new_value) ;
122
147
}
123
148
TerminatorKind :: Call {
@@ -133,7 +158,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
133
158
self . consume_operand ( location, arg) ;
134
159
}
135
160
if let Some ( ( dest, _ /*bb*/ ) ) = destination {
136
- self . mutate_place ( location, * dest, Deep ) ;
161
+ self . mutate_place ( location, * dest, Deep , JustWrite ) ;
137
162
}
138
163
}
139
164
TerminatorKind :: Assert { ref cond, expected : _, ref msg, target : _, cleanup : _ } => {
@@ -156,7 +181,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
156
181
}
157
182
}
158
183
159
- self . mutate_place ( location, * resume_arg, Deep ) ;
184
+ self . mutate_place ( location, * resume_arg, Deep , JustWrite ) ;
160
185
}
161
186
TerminatorKind :: Resume | TerminatorKind :: Return | TerminatorKind :: GeneratorDrop => {
162
187
// Invalidate all borrows of local places
@@ -183,13 +208,13 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
183
208
}
184
209
InlineAsmOperand :: Out { reg : _, late : _, place, .. } => {
185
210
if let Some ( place) = place {
186
- self . mutate_place ( location, place, Shallow ( None ) ) ;
211
+ self . mutate_place ( location, place, Shallow ( None ) , JustWrite ) ;
187
212
}
188
213
}
189
214
InlineAsmOperand :: InOut { reg : _, late : _, ref in_value, out_place } => {
190
215
self . consume_operand ( location, in_value) ;
191
216
if let Some ( out_place) = out_place {
192
- self . mutate_place ( location, out_place, Shallow ( None ) ) ;
217
+ self . mutate_place ( location, out_place, Shallow ( None ) , JustWrite ) ;
193
218
}
194
219
}
195
220
InlineAsmOperand :: Const { value : _ }
@@ -213,7 +238,13 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
213
238
214
239
impl < ' cx , ' tcx > InvalidationGenerator < ' cx , ' tcx > {
215
240
/// Simulates mutation of a place.
216
- fn mutate_place ( & mut self , location : Location , place : Place < ' tcx > , kind : AccessDepth ) {
241
+ fn mutate_place (
242
+ & mut self ,
243
+ location : Location ,
244
+ place : Place < ' tcx > ,
245
+ kind : AccessDepth ,
246
+ _mode : MutateMode ,
247
+ ) {
217
248
self . access_place (
218
249
location,
219
250
place,
0 commit comments