1515use std:: convert:: TryFrom ;
1616use std:: hash:: Hash ;
1717
18+ use rustc:: hir;
1819use rustc:: mir;
1920use rustc:: ty:: { self , Ty } ;
2021use rustc:: ty:: layout:: { self , Size , Align , LayoutOf , TyLayout , HasDataLayout } ;
@@ -270,24 +271,28 @@ where
270271 & self ,
271272 val : ValTy < ' tcx , M :: PointerTag > ,
272273 ) -> 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-
282274 let pointee_type = val. layout . ty . builtin_deref ( true ) . unwrap ( ) . ty ;
283275 let layout = self . layout_of ( pointee_type) ?;
284- let align = layout. align ;
285276
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
291296 } ;
292297 Ok ( MPlaceTy { mplace, layout } )
293298 }
@@ -299,19 +304,25 @@ where
299304 place : MPlaceTy < ' tcx , M :: PointerTag > ,
300305 borrow_kind : Option < mir:: BorrowKind > ,
301306 ) -> 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
311322 } ;
312323 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 ( ) ) ,
315326 } )
316327 }
317328
@@ -845,6 +856,8 @@ where
845856 }
846857
847858 /// 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.
848861 /// This is essentially `force_to_memplace`.
849862 pub fn force_allocation (
850863 & mut self ,
@@ -888,10 +901,11 @@ where
888901 ) -> EvalResult < ' tcx , MPlaceTy < ' tcx , M :: PointerTag > > {
889902 if layout. is_unsized ( ) {
890903 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!
892905 Ok ( MPlaceTy :: dangling ( layout, & self ) )
893906 } else {
894907 let ptr = self . memory . allocate ( layout. size , layout. align , kind) ?;
908+ let ptr = M :: tag_new_allocation ( self , ptr, kind) ?;
895909 Ok ( MPlaceTy :: from_aligned_ptr ( ptr, layout) )
896910 }
897911 }
0 commit comments