use rand::Rng;
-use rustc_mir::interpret::{AllocId, Pointer, InterpResult, Memory, AllocCheck};
+use rustc::ty::layout::HasDataLayout;
+use rustc_mir::interpret::{AllocId, Pointer, InterpResult, Memory, AllocCheck, PointerArithmetic};
use rustc_target::abi::Size;
use crate::{Evaluator, Tag, STACK_ADDR};
let mut global_state = memory.extra.intptrcast.borrow_mut();
let global_state = &mut *global_state;
- let (size, align) = memory.get_size_and_align(ptr.alloc_id, AllocCheck::Live)?;
+ // There is nothing wrong with a raw pointer being cast to an integer only after
+ // it became dangling. Hence `MaybeDead`.
+ let (size, align) = memory.get_size_and_align(ptr.alloc_id, AllocCheck::MaybeDead)?;
let base_addr = match global_state.base_addr.entry(ptr.alloc_id) {
Entry::Occupied(entry) => *entry.get(),
// From next_base_addr + slack, round up to adjust for alignment.
let base_addr = Self::align_addr(global_state.next_base_addr + slack, align.bytes());
entry.insert(base_addr);
+ trace!(
+ "Assigning base address {:#x} to allocation {:?} (slack: {}, align: {})",
+ base_addr, ptr.alloc_id, slack, align.bytes(),
+ );
// Remember next base address. If this allocation is zero-sized, leave a gap
// of at least 1 to avoid two allocations having the same base address.
};
debug_assert_eq!(base_addr % align.bytes(), 0); // sanity check
- Ok(base_addr + ptr.offset.bytes())
+ // Add offset with the right kind of pointer-overflowing arithmetic.
+ let dl = memory.data_layout();
+ Ok(dl.overflowing_offset(base_addr, ptr.offset.bytes()).0)
}
/// Shifts `addr` to make it aligned with `align` by rounding `addr` to the smallest multiple