@@ -5,7 +5,11 @@ use rustc_target::abi::{Abi, Align, Size};
5
5
use crate :: borrow_tracker:: { AccessKind , GlobalStateInner , ProtectorKind , RetagFields } ;
6
6
use rustc_middle:: {
7
7
mir:: { Mutability , RetagKind } ,
8
- ty:: { self , layout:: HasParamEnv , Ty } ,
8
+ ty:: {
9
+ self ,
10
+ layout:: { HasParamEnv , HasTyCtxt } ,
11
+ Ty ,
12
+ } ,
9
13
} ;
10
14
use rustc_span:: def_id:: DefId ;
11
15
@@ -174,6 +178,8 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
174
178
new_tag : BorTag ,
175
179
) -> InterpResult < ' tcx , Option < Provenance > > {
176
180
let this = self . eval_context_mut ( ) ;
181
+ // Make sure the new permission makes sense as the initial permission of a fresh tag.
182
+ assert ! ( new_perm. initial_state. is_initial( ) ) ;
177
183
// Ensure we bail out if the pointer goes out-of-bounds (see miri#1050).
178
184
this. check_ptr_access_align (
179
185
place. ptr ( ) ,
@@ -275,10 +281,6 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
275
281
diagnostics:: AccessCause :: Reborrow ,
276
282
) ?;
277
283
// Record the parent-child pair in the tree.
278
- // FIXME: We should eventually ensure that the following `assert` holds, because
279
- // some "exhaustive" tests consider only the initial configurations that satisfy it.
280
- // The culprit is `Permission::new_active` in `tb_protect_place`.
281
- //assert!(new_perm.initial_state.is_initial());
282
284
tree_borrows. new_child ( orig_tag, new_tag, new_perm. initial_state , range, span) ?;
283
285
drop ( tree_borrows) ;
284
286
@@ -306,15 +308,12 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
306
308
Ok ( Some ( Provenance :: Concrete { alloc_id, tag : new_tag } ) )
307
309
}
308
310
309
- /// Retags an individual pointer, returning the retagged version.
310
- fn tb_retag_reference (
311
+ fn tb_retag_place (
311
312
& mut self ,
312
- val : & ImmTy < ' tcx , Provenance > ,
313
+ place : & MPlaceTy < ' tcx , Provenance > ,
313
314
new_perm : NewPermission ,
314
- ) -> InterpResult < ' tcx , ImmTy < ' tcx , Provenance > > {
315
+ ) -> InterpResult < ' tcx , MPlaceTy < ' tcx , Provenance > > {
315
316
let this = self . eval_context_mut ( ) ;
316
- // We want a place for where the ptr *points to*, so we get one.
317
- let place = this. ref_to_mplace ( val) ?;
318
317
319
318
// Determine the size of the reborrow.
320
319
// For most types this is the entire size of the place, however
@@ -323,7 +322,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
323
322
// then we override the size to do a zero-length reborrow.
324
323
let reborrow_size = match new_perm {
325
324
NewPermission { zero_size : false , .. } =>
326
- this. size_and_align_of_mplace ( & place) ?
325
+ this. size_and_align_of_mplace ( place) ?
327
326
. map ( |( size, _) | size)
328
327
. unwrap_or ( place. layout . size ) ,
329
328
_ => Size :: from_bytes ( 0 ) ,
@@ -339,12 +338,21 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
339
338
let new_tag = this. machine . borrow_tracker . as_mut ( ) . unwrap ( ) . get_mut ( ) . new_ptr ( ) ;
340
339
341
340
// Compute the actual reborrow.
342
- let new_prov = this. tb_reborrow ( & place, reborrow_size, new_perm, new_tag) ?;
341
+ let new_prov = this. tb_reborrow ( place, reborrow_size, new_perm, new_tag) ?;
343
342
344
- // Adjust pointer.
345
- let new_place = place. map_provenance ( |_| new_prov) ;
343
+ // Adjust place.
344
+ Ok ( place. clone ( ) . map_provenance ( |_| new_prov) )
345
+ }
346
346
347
- // Return new pointer.
347
+ /// Retags an individual pointer, returning the retagged version.
348
+ fn tb_retag_reference (
349
+ & mut self ,
350
+ val : & ImmTy < ' tcx , Provenance > ,
351
+ new_perm : NewPermission ,
352
+ ) -> InterpResult < ' tcx , ImmTy < ' tcx , Provenance > > {
353
+ let this = self . eval_context_mut ( ) ;
354
+ let place = this. ref_to_mplace ( val) ?;
355
+ let new_place = this. tb_retag_place ( & place, new_perm) ?;
348
356
Ok ( ImmTy :: from_immediate ( new_place. to_ref ( this) , val. layout ) )
349
357
}
350
358
}
@@ -493,22 +501,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
493
501
/// call.
494
502
///
495
503
/// This is used to ensure soundness of in-place function argument/return passing.
496
- fn tb_protect_place ( & mut self , place : & MPlaceTy < ' tcx , Provenance > ) -> InterpResult < ' tcx > {
504
+ fn tb_protect_place (
505
+ & mut self ,
506
+ place : & MPlaceTy < ' tcx , Provenance > ,
507
+ ) -> InterpResult < ' tcx , MPlaceTy < ' tcx , Provenance > > {
497
508
let this = self . eval_context_mut ( ) ;
498
509
499
- // We have to turn the place into a pointer to use the usual retagging logic.
500
- // (The pointer type does not matter, so we use a raw pointer.)
501
- let ptr = this. mplace_to_ref ( place) ?;
502
- // Reborrow it. With protection! That is the entire point.
510
+ // Retag it. With protection! That is the entire point.
503
511
let new_perm = NewPermission {
504
- initial_state : Permission :: new_active ( ) ,
512
+ initial_state : Permission :: new_reserved (
513
+ place. layout . ty . is_freeze ( this. tcx ( ) , this. param_env ( ) ) ,
514
+ ) ,
505
515
zero_size : false ,
506
516
protector : Some ( ProtectorKind :: StrongProtector ) ,
507
517
} ;
508
- let _new_ptr = this. tb_retag_reference ( & ptr, new_perm) ?;
509
- // We just throw away `new_ptr`, so nobody can access this memory while it is protected.
510
-
511
- Ok ( ( ) )
518
+ this. tb_retag_place ( place, new_perm)
512
519
}
513
520
514
521
/// Mark the given tag as exposed. It was found on a pointer with the given AllocId.
0 commit comments