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:
commit
c51cd7a3fd
@ -105,6 +105,8 @@ impl<'mir, 'tcx> GlobalStateInner {
|
|||||||
trace!("Exposing allocation id {:?}", alloc_id);
|
trace!("Exposing allocation id {:?}", alloc_id);
|
||||||
|
|
||||||
let mut global_state = ecx.machine.intptrcast.borrow_mut();
|
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 {
|
if global_state.provenance_mode == ProvenanceMode::Permissive {
|
||||||
global_state.exposed.insert(alloc_id);
|
global_state.exposed.insert(alloc_id);
|
||||||
}
|
}
|
||||||
@ -118,12 +120,17 @@ impl<'mir, 'tcx> GlobalStateInner {
|
|||||||
|
|
||||||
let global_state = ecx.machine.intptrcast.borrow();
|
let global_state = ecx.machine.intptrcast.borrow();
|
||||||
|
|
||||||
// In legacy mode, we have to support int2ptr transmutes,
|
match global_state.provenance_mode {
|
||||||
// so just pretend they do the same thing as a cast.
|
ProvenanceMode::Legacy => {
|
||||||
if global_state.provenance_mode == ProvenanceMode::Legacy {
|
// In legacy mode, we have to support int2ptr transmutes,
|
||||||
Self::ptr_from_addr_cast(ecx, addr)
|
// so just pretend they do the same thing as a cast.
|
||||||
} else {
|
Self::ptr_from_addr_cast(ecx, addr)
|
||||||
Pointer::new(None, Size::from_bytes(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();
|
let global_state = ecx.machine.intptrcast.borrow();
|
||||||
|
|
||||||
if global_state.provenance_mode == ProvenanceMode::Strict {
|
match global_state.provenance_mode {
|
||||||
Pointer::new(None, Size::from_bytes(addr))
|
ProvenanceMode::Legacy => {
|
||||||
} else if 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);
|
let alloc_id = Self::alloc_id_from_addr(ecx, addr);
|
||||||
|
Pointer::new(
|
||||||
Pointer::new(
|
alloc_id.map(|alloc_id| {
|
||||||
alloc_id
|
Tag::Concrete(ConcreteTag { alloc_id, sb: SbTag::Untagged })
|
||||||
.map(|alloc_id| Tag::Concrete(ConcreteTag { alloc_id, sb: SbTag::Untagged })),
|
}),
|
||||||
Size::from_bytes(addr),
|
Size::from_bytes(addr),
|
||||||
)
|
)
|
||||||
} else {
|
}
|
||||||
Pointer::new(Some(Tag::Wildcard), 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 {
|
let alloc_id = if let Tag::Concrete(concrete) = tag {
|
||||||
concrete.alloc_id
|
concrete.alloc_id
|
||||||
} else {
|
} else {
|
||||||
|
// A wildcard pointer.
|
||||||
|
assert_eq!(ecx.machine.intptrcast.borrow().provenance_mode, ProvenanceMode::Permissive);
|
||||||
GlobalStateInner::alloc_id_from_addr(ecx, addr.bytes())?
|
GlobalStateInner::alloc_id_from_addr(ecx, addr.bytes())?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -652,19 +652,18 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
|
|||||||
intptrcast::GlobalStateInner::ptr_from_addr_transmute(ecx, addr)
|
intptrcast::GlobalStateInner::ptr_from_addr_transmute(ecx, addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn expose_ptr(
|
fn expose_ptr(
|
||||||
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||||
ptr: Pointer<Self::PointerTag>,
|
ptr: Pointer<Self::PointerTag>,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
let tag = ptr.provenance;
|
match ptr.provenance {
|
||||||
|
Tag::Concrete(concrete) =>
|
||||||
if let Tag::Concrete(concrete) = tag {
|
intptrcast::GlobalStateInner::expose_addr(ecx, concrete.alloc_id),
|
||||||
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -676,12 +675,13 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
|
|||||||
) -> Option<(AllocId, Size, Self::TagExtra)> {
|
) -> Option<(AllocId, Size, Self::TagExtra)> {
|
||||||
let rel = intptrcast::GlobalStateInner::abs_ptr_to_rel(ecx, ptr);
|
let rel = intptrcast::GlobalStateInner::abs_ptr_to_rel(ecx, ptr);
|
||||||
|
|
||||||
let sb = match ptr.provenance {
|
rel.map(|(alloc_id, size)| {
|
||||||
Tag::Concrete(ConcreteTag { sb, .. }) => sb,
|
let sb = match ptr.provenance {
|
||||||
Tag::Wildcard => SbTag::Untagged,
|
Tag::Concrete(ConcreteTag { sb, .. }) => sb,
|
||||||
};
|
Tag::Wildcard => SbTag::Untagged,
|
||||||
|
};
|
||||||
rel.map(|(alloc_id, size)| (alloc_id, size, sb))
|
(alloc_id, size, sb)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user