Skip to content

Commit c51cd7a

Browse files
committed
Auto merge of #2146 - RalfJung:int2ptr, r=RalfJung
clean up int2ptr code a bit Follow-up to #2059
2 parents ab03d32 + 697dca2 commit c51cd7a

File tree

2 files changed

+49
-32
lines changed

2 files changed

+49
-32
lines changed

src/intptrcast.rs

+35-18
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ impl<'mir, 'tcx> GlobalStateInner {
105105
trace!("Exposing allocation id {:?}", alloc_id);
106106

107107
let mut global_state = ecx.machine.intptrcast.borrow_mut();
108+
// In legacy and strict mode, we don't need this, so we can save some cycles
109+
// by not tracking it.
108110
if global_state.provenance_mode == ProvenanceMode::Permissive {
109111
global_state.exposed.insert(alloc_id);
110112
}
@@ -118,12 +120,17 @@ impl<'mir, 'tcx> GlobalStateInner {
118120

119121
let global_state = ecx.machine.intptrcast.borrow();
120122

121-
// In legacy mode, we have to support int2ptr transmutes,
122-
// so just pretend they do the same thing as a cast.
123-
if global_state.provenance_mode == ProvenanceMode::Legacy {
124-
Self::ptr_from_addr_cast(ecx, addr)
125-
} else {
126-
Pointer::new(None, Size::from_bytes(addr))
123+
match global_state.provenance_mode {
124+
ProvenanceMode::Legacy => {
125+
// In legacy mode, we have to support int2ptr transmutes,
126+
// so just pretend they do the same thing as a cast.
127+
Self::ptr_from_addr_cast(ecx, addr)
128+
}
129+
ProvenanceMode::Permissive | ProvenanceMode::Strict => {
130+
// Both of these modes consider transmuted pointers to be "invalid" (`None`
131+
// provenance).
132+
Pointer::new(None, Size::from_bytes(addr))
133+
}
127134
}
128135
}
129136

@@ -135,18 +142,26 @@ impl<'mir, 'tcx> GlobalStateInner {
135142

136143
let global_state = ecx.machine.intptrcast.borrow();
137144

138-
if global_state.provenance_mode == ProvenanceMode::Strict {
139-
Pointer::new(None, Size::from_bytes(addr))
140-
} else if global_state.provenance_mode == ProvenanceMode::Legacy {
141-
let alloc_id = Self::alloc_id_from_addr(ecx, addr);
142-
143-
Pointer::new(
144-
alloc_id
145-
.map(|alloc_id| Tag::Concrete(ConcreteTag { alloc_id, sb: SbTag::Untagged })),
146-
Size::from_bytes(addr),
147-
)
148-
} else {
149-
Pointer::new(Some(Tag::Wildcard), Size::from_bytes(addr))
145+
match global_state.provenance_mode {
146+
ProvenanceMode::Legacy => {
147+
// Determine the allocation this points to at cast time.
148+
let alloc_id = Self::alloc_id_from_addr(ecx, addr);
149+
Pointer::new(
150+
alloc_id.map(|alloc_id| {
151+
Tag::Concrete(ConcreteTag { alloc_id, sb: SbTag::Untagged })
152+
}),
153+
Size::from_bytes(addr),
154+
)
155+
}
156+
ProvenanceMode::Strict => {
157+
// We don't support int2ptr casts in this mode (i.e., we treat them like
158+
// transmutes).
159+
Pointer::new(None, Size::from_bytes(addr))
160+
}
161+
ProvenanceMode::Permissive => {
162+
// This is how wildcard pointers are born.
163+
Pointer::new(Some(Tag::Wildcard), Size::from_bytes(addr))
164+
}
150165
}
151166
}
152167

@@ -215,6 +230,8 @@ impl<'mir, 'tcx> GlobalStateInner {
215230
let alloc_id = if let Tag::Concrete(concrete) = tag {
216231
concrete.alloc_id
217232
} else {
233+
// A wildcard pointer.
234+
assert_eq!(ecx.machine.intptrcast.borrow().provenance_mode, ProvenanceMode::Permissive);
218235
GlobalStateInner::alloc_id_from_addr(ecx, addr.bytes())?
219236
};
220237

src/machine.rs

+14-14
Original file line numberDiff line numberDiff line change
@@ -652,19 +652,18 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
652652
intptrcast::GlobalStateInner::ptr_from_addr_transmute(ecx, addr)
653653
}
654654

655-
#[inline(always)]
656655
fn expose_ptr(
657656
ecx: &mut InterpCx<'mir, 'tcx, Self>,
658657
ptr: Pointer<Self::PointerTag>,
659658
) -> InterpResult<'tcx> {
660-
let tag = ptr.provenance;
661-
662-
if let Tag::Concrete(concrete) = tag {
663-
intptrcast::GlobalStateInner::expose_addr(ecx, concrete.alloc_id);
659+
match ptr.provenance {
660+
Tag::Concrete(concrete) =>
661+
intptrcast::GlobalStateInner::expose_addr(ecx, concrete.alloc_id),
662+
Tag::Wildcard => {
663+
// No need to do anything for wildcard pointers as
664+
// their provenances have already been previously exposed.
665+
}
664666
}
665-
666-
// No need to do anything for wildcard pointers as
667-
// their provenances have already been previously exposed.
668667
Ok(())
669668
}
670669

@@ -676,12 +675,13 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
676675
) -> Option<(AllocId, Size, Self::TagExtra)> {
677676
let rel = intptrcast::GlobalStateInner::abs_ptr_to_rel(ecx, ptr);
678677

679-
let sb = match ptr.provenance {
680-
Tag::Concrete(ConcreteTag { sb, .. }) => sb,
681-
Tag::Wildcard => SbTag::Untagged,
682-
};
683-
684-
rel.map(|(alloc_id, size)| (alloc_id, size, sb))
678+
rel.map(|(alloc_id, size)| {
679+
let sb = match ptr.provenance {
680+
Tag::Concrete(ConcreteTag { sb, .. }) => sb,
681+
Tag::Wildcard => SbTag::Untagged,
682+
};
683+
(alloc_id, size, sb)
684+
})
685685
}
686686

687687
#[inline(always)]

0 commit comments

Comments
 (0)