Skip to content

Commit c6e4f76

Browse files
committed
allow dangling ptr-to-int casts; use force_bits for ptr comparison
1 parent 457c823 commit c6e4f76

File tree

2 files changed

+12
-1
lines changed

2 files changed

+12
-1
lines changed

src/intptrcast.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ impl<'mir, 'tcx> GlobalState {
7575
let mut global_state = memory.extra.intptrcast.borrow_mut();
7676
let global_state = &mut *global_state;
7777

78-
let (size, align) = memory.get_size_and_align(ptr.alloc_id, AllocCheck::Live)?;
78+
// There is nothing wrong with a raw pointer being cast to an integer only after
79+
// it became dangling. Hence `MaybeDead`.
80+
let (size, align) = memory.get_size_and_align(ptr.alloc_id, AllocCheck::MaybeDead)?;
7981

8082
let base_addr = match global_state.base_addr.entry(ptr.alloc_id) {
8183
Entry::Occupied(entry) => *entry.get(),

src/operator.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
5959
// If intptrcast is enabled, treat everything of integer *type* at integer *value*.
6060
if self.memory().extra.rng.is_some() && left.layout.ty.is_integral() {
6161
// This is actually an integer operation, so dispatch back to the core engine.
62+
// TODO: Once intptrcast is the default, librustc_mir should never even call us
63+
// for integer types.
6264
assert!(right.layout.ty.is_integral());
6365
let l_bits = self.force_bits(left.imm.to_scalar()?, left.layout.size)?;
6466
let r_bits = self.force_bits(right.imm.to_scalar()?, right.layout.size)?;
@@ -186,6 +188,13 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
186188
right: Scalar<Tag>,
187189
) -> InterpResult<'tcx, bool> {
188190
let size = self.pointer_size();
191+
if self.memory().extra.rng.is_some() {
192+
// Just compare the integers.
193+
// TODO: Do we really want to *always* do that, even when comparing two live in-bounds pointers?
194+
let left = self.force_bits(left, size)?;
195+
let right = self.force_bits(right, size)?;
196+
return Ok(left == right);
197+
}
189198
Ok(match (left, right) {
190199
(Scalar::Raw { .. }, Scalar::Raw { .. }) =>
191200
left.to_bits(size)? == right.to_bits(size)?,

0 commit comments

Comments
 (0)