Auto merge of #2146 - RalfJung:int2ptr, r=RalfJung

clean up int2ptr code a bit

Follow-up to https://github.com/rust-lang/miri/pull/2059
This commit is contained in:
bors 2022-05-23 08:07:43 +00:00
commit c51cd7a3fd
2 changed files with 49 additions and 32 deletions

View File

@ -105,6 +105,8 @@ impl<'mir, 'tcx> GlobalStateInner {
trace!("Exposing allocation id {:?}", alloc_id);
let mut global_state = ecx.machine.intptrcast.borrow_mut();
// In legacy and strict mode, we don't need this, so we can save some cycles
// by not tracking it.
if global_state.provenance_mode == ProvenanceMode::Permissive {
global_state.exposed.insert(alloc_id);
}
@ -118,12 +120,17 @@ impl<'mir, 'tcx> GlobalStateInner {
let global_state = ecx.machine.intptrcast.borrow();
// In legacy mode, we have to support int2ptr transmutes,
// so just pretend they do the same thing as a cast.
if global_state.provenance_mode == ProvenanceMode::Legacy {
Self::ptr_from_addr_cast(ecx, addr)
} else {
Pointer::new(None, Size::from_bytes(addr))
match global_state.provenance_mode {
ProvenanceMode::Legacy => {
// In legacy mode, we have to support int2ptr transmutes,
// so just pretend they do the same thing as a cast.
Self::ptr_from_addr_cast(ecx, addr)
}
ProvenanceMode::Permissive | ProvenanceMode::Strict => {
// Both of these modes consider transmuted pointers to be "invalid" (`None`
// provenance).
Pointer::new(None, Size::from_bytes(addr))
}
}
}
@ -135,18 +142,26 @@ impl<'mir, 'tcx> GlobalStateInner {
let global_state = ecx.machine.intptrcast.borrow();
if global_state.provenance_mode == ProvenanceMode::Strict {
Pointer::new(None, Size::from_bytes(addr))
} else if global_state.provenance_mode == ProvenanceMode::Legacy {
let alloc_id = Self::alloc_id_from_addr(ecx, addr);
Pointer::new(
alloc_id
.map(|alloc_id| Tag::Concrete(ConcreteTag { alloc_id, sb: SbTag::Untagged })),
Size::from_bytes(addr),
)
} else {
Pointer::new(Some(Tag::Wildcard), Size::from_bytes(addr))
match global_state.provenance_mode {
ProvenanceMode::Legacy => {
// Determine the allocation this points to at cast time.
let alloc_id = Self::alloc_id_from_addr(ecx, addr);
Pointer::new(
alloc_id.map(|alloc_id| {
Tag::Concrete(ConcreteTag { alloc_id, sb: SbTag::Untagged })
}),
Size::from_bytes(addr),
)
}
ProvenanceMode::Strict => {
// We don't support int2ptr casts in this mode (i.e., we treat them like
// transmutes).
Pointer::new(None, Size::from_bytes(addr))
}
ProvenanceMode::Permissive => {
// This is how wildcard pointers are born.
Pointer::new(Some(Tag::Wildcard), Size::from_bytes(addr))
}
}
}
@ -215,6 +230,8 @@ impl<'mir, 'tcx> GlobalStateInner {
let alloc_id = if let Tag::Concrete(concrete) = tag {
concrete.alloc_id
} else {
// A wildcard pointer.
assert_eq!(ecx.machine.intptrcast.borrow().provenance_mode, ProvenanceMode::Permissive);
GlobalStateInner::alloc_id_from_addr(ecx, addr.bytes())?
};

View File

@ -652,19 +652,18 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
intptrcast::GlobalStateInner::ptr_from_addr_transmute(ecx, addr)
}
#[inline(always)]
fn expose_ptr(
ecx: &mut InterpCx<'mir, 'tcx, Self>,
ptr: Pointer<Self::PointerTag>,
) -> InterpResult<'tcx> {
let tag = ptr.provenance;
if let Tag::Concrete(concrete) = tag {
intptrcast::GlobalStateInner::expose_addr(ecx, concrete.alloc_id);
match ptr.provenance {
Tag::Concrete(concrete) =>
intptrcast::GlobalStateInner::expose_addr(ecx, concrete.alloc_id),
Tag::Wildcard => {
// No need to do anything for wildcard pointers as
// their provenances have already been previously exposed.
}
}
// No need to do anything for wildcard pointers as
// their provenances have already been previously exposed.
Ok(())
}
@ -676,12 +675,13 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
) -> Option<(AllocId, Size, Self::TagExtra)> {
let rel = intptrcast::GlobalStateInner::abs_ptr_to_rel(ecx, ptr);
let sb = match ptr.provenance {
Tag::Concrete(ConcreteTag { sb, .. }) => sb,
Tag::Wildcard => SbTag::Untagged,
};
rel.map(|(alloc_id, size)| (alloc_id, size, sb))
rel.map(|(alloc_id, size)| {
let sb = match ptr.provenance {
Tag::Concrete(ConcreteTag { sb, .. }) => sb,
Tag::Wildcard => SbTag::Untagged,
};
(alloc_id, size, sb)
})
}
#[inline(always)]