-use rustc::ty::layout::HasDataLayout;
-use rustc_mir::interpret::{AllocId, Pointer, InterpResult, Memory, AllocCheck, PointerArithmetic};
-use rustc_target::abi::Size;
+use rustc_data_structures::fx::FxHashMap;
+use rustc_target::abi::{Size, HasDataLayout};
/// `AllocExtra` because function pointers also have a base address, and
/// they do not have an `AllocExtra`.
/// This is the inverse of `int_to_ptr_map`.
/// `AllocExtra` because function pointers also have a base address, and
/// they do not have an `AllocExtra`.
/// This is the inverse of `int_to_ptr_map`.
/// This is used as a memory address when a new pointer is casted to an integer. It
/// is always larger than any address that was previously made part of a block.
pub next_base_addr: u64,
/// This is used as a memory address when a new pointer is casted to an integer. It
/// is always larger than any address that was previously made part of a block.
pub next_base_addr: u64,
- memory: &Memory<'mir, 'tcx, Evaluator<'tcx>>,
+ memory: &Memory<'mir, 'tcx, Evaluator<'mir, 'tcx>>,
-
- Ok(match global_state.int_to_ptr_map.binary_search_by_key(&int, |(addr, _)| *addr) {
+ let pos = global_state.int_to_ptr_map.binary_search_by_key(&int, |(addr, _)| *addr);
+
+ // The int must be in-bounds after being cast to a pointer, so we error
+ // with `CheckInAllocMsg::InboundsTest`.
+ Ok(match pos {
Ok(pos) => {
let (_, alloc_id) = global_state.int_to_ptr_map[pos];
// `int` is equal to the starting address for an allocation, the offset should be
// zero. The pointer is untagged because it was created from a cast
Pointer::new_with_tag(alloc_id, Size::from_bytes(0), Tag::Untagged)
Ok(pos) => {
let (_, alloc_id) = global_state.int_to_ptr_map[pos];
// `int` is equal to the starting address for an allocation, the offset should be
// zero. The pointer is untagged because it was created from a cast
Pointer::new_with_tag(alloc_id, Size::from_bytes(0), Tag::Untagged)
Err(pos) => {
// This is the largest of the adresses smaller than `int`,
// i.e. the greatest lower bound (glb)
Err(pos) => {
// This is the largest of the adresses smaller than `int`,
// i.e. the greatest lower bound (glb)
// This never overflows because `int >= glb`
let offset = int - glb;
// If the offset exceeds the size of the allocation, this access is illegal
// This never overflows because `int >= glb`
let offset = int - glb;
// If the offset exceeds the size of the allocation, this access is illegal
// This pointer is untagged because it was created from a cast
Pointer::new_with_tag(alloc_id, Size::from_bytes(offset), Tag::Untagged)
} else {
// This pointer is untagged because it was created from a cast
Pointer::new_with_tag(alloc_id, Size::from_bytes(offset), Tag::Untagged)
} else {
- memory: &Memory<'mir, 'tcx, Evaluator<'tcx>>,
+ memory: &Memory<'mir, 'tcx, Evaluator<'mir, 'tcx>>,
) -> InterpResult<'tcx, u64> {
let mut global_state = memory.extra.intptrcast.borrow_mut();
let global_state = &mut *global_state;
) -> InterpResult<'tcx, u64> {
let mut global_state = memory.extra.intptrcast.borrow_mut();
let global_state = &mut *global_state;
// There is nothing wrong with a raw pointer being cast to an integer only after
// it became dangling. Hence `MaybeDead`.
// There is nothing wrong with a raw pointer being cast to an integer only after
// it became dangling. Hence `MaybeDead`.
Entry::Occupied(entry) => *entry.get(),
Entry::Vacant(entry) => {
// This allocation does not have a base address yet, pick one.
Entry::Occupied(entry) => *entry.get(),
Entry::Vacant(entry) => {
// This allocation does not have a base address yet, pick one.
global_state.next_base_addr = base_addr.checked_add(max(size.bytes(), 1)).unwrap();
// Given that `next_base_addr` increases in each allocation, pushing the
// corresponding tuple keeps `int_to_ptr_map` sorted
global_state.next_base_addr = base_addr.checked_add(max(size.bytes(), 1)).unwrap();
// Given that `next_base_addr` increases in each allocation, pushing the
// corresponding tuple keeps `int_to_ptr_map` sorted
// 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)
// 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)