15
15
use std:: convert:: TryFrom ;
16
16
use std:: hash:: Hash ;
17
17
18
+ use rustc:: hir;
18
19
use rustc:: mir;
19
20
use rustc:: ty:: { self , Ty } ;
20
21
use rustc:: ty:: layout:: { self , Size , Align , LayoutOf , TyLayout , HasDataLayout } ;
@@ -270,24 +271,28 @@ where
270
271
& self ,
271
272
val : ValTy < ' tcx , M :: PointerTag > ,
272
273
) -> EvalResult < ' tcx , MPlaceTy < ' tcx , M :: PointerTag > > {
273
- let ptr = match val. to_scalar_ptr ( ) ? {
274
- Scalar :: Ptr ( ptr) if M :: ENABLE_PTR_TRACKING_HOOKS => {
275
- // Machine might want to track the `*` operator
276
- let tag = M :: tag_dereference ( self , ptr, val. layout . ty ) ?;
277
- Scalar :: Ptr ( Pointer :: new_with_tag ( ptr. alloc_id , ptr. offset , tag) )
278
- }
279
- other => other,
280
- } ;
281
-
282
274
let pointee_type = val. layout . ty . builtin_deref ( true ) . unwrap ( ) . ty ;
283
275
let layout = self . layout_of ( pointee_type) ?;
284
- let align = layout. align ;
285
276
286
- let mplace = match * val {
287
- Value :: Scalar ( _) =>
288
- MemPlace { ptr, align, meta : None } ,
289
- Value :: ScalarPair ( _, meta) =>
290
- MemPlace { ptr, align, meta : Some ( meta. not_undef ( ) ?) } ,
277
+ let align = layout. align ;
278
+ let meta = val. to_meta ( ) ?;
279
+ let ptr = val. to_scalar_ptr ( ) ?;
280
+ let mplace = MemPlace { ptr, align, meta } ;
281
+ // Pointer tag tracking might want to adjust the tag.
282
+ let mplace = if M :: ENABLE_PTR_TRACKING_HOOKS {
283
+ let ( size, _) = self . size_and_align_of ( meta, layout) ?
284
+ // for extern types, just cover what we can
285
+ . unwrap_or_else ( || layout. size_and_align ( ) ) ;
286
+ let mutbl = match val. layout . ty . sty {
287
+ // `builtin_deref` considers boxes immutable, that's useless for our purposes
288
+ ty:: Ref ( _, _, mutbl) => Some ( mutbl) ,
289
+ ty:: Adt ( def, _) if def. is_box ( ) => Some ( hir:: MutMutable ) ,
290
+ ty:: RawPtr ( _) => None ,
291
+ _ => bug ! ( "Unexpected pointer type {}" , val. layout. ty. sty) ,
292
+ } ;
293
+ M :: tag_dereference ( self , mplace, pointee_type, size, mutbl) ?
294
+ } else {
295
+ mplace
291
296
} ;
292
297
Ok ( MPlaceTy { mplace, layout } )
293
298
}
@@ -299,19 +304,25 @@ where
299
304
place : MPlaceTy < ' tcx , M :: PointerTag > ,
300
305
borrow_kind : Option < mir:: BorrowKind > ,
301
306
) -> EvalResult < ' tcx , Value < M :: PointerTag > > {
302
- let ptr = match place. ptr {
303
- Scalar :: Ptr ( ptr) if M :: ENABLE_PTR_TRACKING_HOOKS => {
304
- // Machine might want to track the `&` operator
305
- let ( size, _) = self . size_and_align_of_mplace ( place) ?
306
- . expect ( "create_ref cannot determine size" ) ;
307
- let tag = M :: tag_reference ( self , ptr, place. layout . ty , size, borrow_kind) ?;
308
- Scalar :: Ptr ( Pointer :: new_with_tag ( ptr. alloc_id , ptr. offset , tag) )
309
- } ,
310
- other => other,
307
+ // Pointer tag tracking might want to adjust the tag
308
+ let place = if M :: ENABLE_PTR_TRACKING_HOOKS {
309
+ let ( size, _) = self . size_and_align_of_mplace ( place) ?
310
+ // for extern types, just cover what we can
311
+ . unwrap_or_else ( || place. layout . size_and_align ( ) ) ;
312
+ let mutbl = match borrow_kind {
313
+ Some ( mir:: BorrowKind :: Mut { .. } ) |
314
+ Some ( mir:: BorrowKind :: Unique ) =>
315
+ Some ( hir:: MutMutable ) ,
316
+ Some ( _) => Some ( hir:: MutImmutable ) ,
317
+ None => None ,
318
+ } ;
319
+ M :: tag_reference ( self , * place, place. layout . ty , size, mutbl) ?
320
+ } else {
321
+ * place
311
322
} ;
312
323
Ok ( match place. meta {
313
- None => Value :: Scalar ( ptr. into ( ) ) ,
314
- Some ( meta) => Value :: ScalarPair ( ptr. into ( ) , meta. into ( ) ) ,
324
+ None => Value :: Scalar ( place . ptr . into ( ) ) ,
325
+ Some ( meta) => Value :: ScalarPair ( place . ptr . into ( ) , meta. into ( ) ) ,
315
326
} )
316
327
}
317
328
@@ -845,6 +856,8 @@ where
845
856
}
846
857
847
858
/// Make sure that a place is in memory, and return where it is.
859
+ /// If the place currently refers to a local that doesn't yet have a matching allocation,
860
+ /// create such an allocation.
848
861
/// This is essentially `force_to_memplace`.
849
862
pub fn force_allocation (
850
863
& mut self ,
@@ -888,10 +901,11 @@ where
888
901
) -> EvalResult < ' tcx , MPlaceTy < ' tcx , M :: PointerTag > > {
889
902
if layout. is_unsized ( ) {
890
903
assert ! ( self . tcx. features( ) . unsized_locals, "cannot alloc memory for unsized type" ) ;
891
- // FIXME: What should we do here?
904
+ // FIXME: What should we do here? We should definitely also tag!
892
905
Ok ( MPlaceTy :: dangling ( layout, & self ) )
893
906
} else {
894
907
let ptr = self . memory . allocate ( layout. size , layout. align , kind) ?;
908
+ let ptr = M :: tag_new_allocation ( self , ptr, kind) ?;
895
909
Ok ( MPlaceTy :: from_aligned_ptr ( ptr, layout) )
896
910
}
897
911
}
0 commit comments