Skip to content

Commit e55f494

Browse files
committed
borrow tracking: simplify provenance updating
1 parent a73c86d commit e55f494

File tree

2 files changed

+20
-55
lines changed
  • src/tools/miri/src/borrow_tracker

2 files changed

+20
-55
lines changed

src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs

+12-25
Original file line numberDiff line numberDiff line change
@@ -604,16 +604,15 @@ impl<'mir: 'ecx, 'tcx: 'mir, 'ecx> EvalContextPrivExt<'mir, 'tcx, 'ecx>
604604
{
605605
}
606606
trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'mir, 'tcx> {
607-
/// Returns the `AllocId` the reborrow was done in, if some actual borrow stack manipulation
608-
/// happened.
607+
/// Returns the provenance that should be used henceforth.
609608
fn sb_reborrow(
610609
&mut self,
611610
place: &MPlaceTy<'tcx, Provenance>,
612611
size: Size,
613612
new_perm: NewPermission,
614613
new_tag: BorTag,
615614
retag_info: RetagInfo, // diagnostics info about this retag
616-
) -> InterpResult<'tcx, Option<AllocId>> {
615+
) -> InterpResult<'tcx, Option<Provenance>> {
617616
let this = self.eval_context_mut();
618617
// Ensure we bail out if the pointer goes out-of-bounds (see miri#1050).
619618
this.check_ptr_access_align(place.ptr, size, Align::ONE, CheckInAllocMsg::InboundsTest)?;
@@ -695,11 +694,14 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
695694
// pointer tagging for example all calls to get_unchecked on them are invalid.
696695
if let Ok((alloc_id, base_offset, orig_tag)) = this.ptr_try_get_alloc_id(place.ptr) {
697696
log_creation(this, Some((alloc_id, base_offset, orig_tag)))?;
698-
return Ok(Some(alloc_id));
697+
// Still give it the new provenance, it got retagged after all.
698+
return Ok(Some(Provenance::Concrete { alloc_id, tag: new_tag }));
699+
} else {
700+
// This pointer doesn't come with an AllocId. :shrug:
701+
log_creation(this, None)?;
702+
// Provenance unchanged.
703+
return Ok(place.ptr.provenance);
699704
}
700-
// This pointer doesn't come with an AllocId. :shrug:
701-
log_creation(this, None)?;
702-
return Ok(None);
703705
}
704706

705707
let (alloc_id, base_offset, orig_tag) = this.ptr_get_alloc_id(place.ptr)?;
@@ -804,7 +806,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
804806
}
805807
}
806808

807-
Ok(Some(alloc_id))
809+
Ok(Some(Provenance::Concrete { alloc_id, tag: new_tag }))
808810
}
809811

810812
/// Retags an individual pointer, returning the retagged version.
@@ -831,25 +833,10 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
831833
let new_tag = this.machine.borrow_tracker.as_mut().unwrap().get_mut().new_ptr();
832834

833835
// Reborrow.
834-
let alloc_id = this.sb_reborrow(&place, size, new_perm, new_tag, info)?;
836+
let new_prov = this.sb_reborrow(&place, size, new_perm, new_tag, info)?;
835837

836838
// Adjust pointer.
837-
let new_place = place.map_provenance(|p| {
838-
p.map(|prov| {
839-
match alloc_id {
840-
Some(alloc_id) => {
841-
// If `reborrow` could figure out the AllocId of this ptr, hard-code it into the new one.
842-
// Even if we started out with a wildcard, this newly retagged pointer is tied to that allocation.
843-
Provenance::Concrete { alloc_id, tag: new_tag }
844-
}
845-
None => {
846-
// Looks like this has to stay a wildcard pointer.
847-
assert!(matches!(prov, Provenance::Wildcard));
848-
Provenance::Wildcard
849-
}
850-
}
851-
})
852-
});
839+
let new_place = place.map_provenance(|_| new_prov);
853840

854841
// Return new pointer.
855842
Ok(ImmTy::from_immediate(new_place.to_ref(this), val.layout))

src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs

+8-30
Original file line numberDiff line numberDiff line change
@@ -161,22 +161,14 @@ impl<'mir: 'ecx, 'tcx: 'mir, 'ecx> EvalContextPrivExt<'mir, 'tcx, 'ecx>
161161
{
162162
}
163163
trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'mir, 'tcx> {
164-
/// Returns the `AllocId` the reborrow was done in, if there is some actual
165-
/// memory associated with this pointer. Returns `None` if there is no actual
166-
/// memory allocated. Also checks that the reborrow of size `ptr_size` is
167-
/// within bounds of the allocation.
168-
///
169-
/// Also returns the tag that the pointer should get, which is essentially
170-
/// `if new_perm.is_some() { new_tag } else { parent_tag }` along with
171-
/// some logging (always) and fake reads (if `new_perm` is
172-
/// `Some(NewPermission { perform_read_access: true }`).
164+
/// Returns the provenance that should be used henceforth.
173165
fn tb_reborrow(
174166
&mut self,
175167
place: &MPlaceTy<'tcx, Provenance>, // parent tag extracted from here
176168
ptr_size: Size,
177169
new_perm: NewPermission,
178170
new_tag: BorTag,
179-
) -> InterpResult<'tcx, Option<(AllocId, BorTag)>> {
171+
) -> InterpResult<'tcx, Option<Provenance>> {
180172
let this = self.eval_context_mut();
181173
// Ensure we bail out if the pointer goes out-of-bounds (see miri#1050).
182174
this.check_ptr_access_align(
@@ -222,13 +214,14 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
222214
place.layout.ty,
223215
);
224216
log_creation(this, None)?;
225-
return Ok(None);
217+
// Keep original provenance.
218+
return Ok(place.ptr.provenance);
226219
}
227220
};
228221
log_creation(this, Some((alloc_id, base_offset, parent_prov)))?;
229222

230223
let orig_tag = match parent_prov {
231-
ProvenanceExtra::Wildcard => return Ok(None), // TODO: handle wildcard pointers
224+
ProvenanceExtra::Wildcard => return Ok(place.ptr.provenance), // TODO: handle wildcard pointers
232225
ProvenanceExtra::Concrete(tag) => tag,
233226
};
234227

@@ -279,7 +272,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
279272

280273
// Record the parent-child pair in the tree.
281274
tree_borrows.new_child(orig_tag, new_tag, new_perm.initial_state, range, span)?;
282-
Ok(Some((alloc_id, new_tag)))
275+
Ok(Some(Provenance::Concrete { alloc_id, tag: new_tag }))
283276
}
284277

285278
/// Retags an individual pointer, returning the retagged version.
@@ -315,25 +308,10 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
315308
let new_tag = this.machine.borrow_tracker.as_mut().unwrap().get_mut().new_ptr();
316309

317310
// Compute the actual reborrow.
318-
let reborrowed = this.tb_reborrow(&place, reborrow_size, new_perm, new_tag)?;
311+
let new_prov = this.tb_reborrow(&place, reborrow_size, new_perm, new_tag)?;
319312

320313
// Adjust pointer.
321-
let new_place = place.map_provenance(|p| {
322-
p.map(|prov| {
323-
match reborrowed {
324-
Some((alloc_id, actual_tag)) => {
325-
// If `reborrow` could figure out the AllocId of this ptr, hard-code it into the new one.
326-
// Even if we started out with a wildcard, this newly retagged pointer is tied to that allocation.
327-
Provenance::Concrete { alloc_id, tag: actual_tag }
328-
}
329-
None => {
330-
// Looks like this has to stay a wildcard pointer.
331-
assert!(matches!(prov, Provenance::Wildcard));
332-
Provenance::Wildcard
333-
}
334-
}
335-
})
336-
});
314+
let new_place = place.map_provenance(|_| new_prov);
337315

338316
// Return new pointer.
339317
Ok(ImmTy::from_immediate(new_place.to_ref(this), val.layout))

0 commit comments

Comments
 (0)