Skip to content

Commit 11457a4

Browse files
committed
fix comparing function pointers with intptrcast
1 parent 1ec279f commit 11457a4

File tree

4 files changed

+29
-20
lines changed

4 files changed

+29
-20
lines changed

src/intptrcast.rs

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,26 @@
1-
use std::cell::{Cell, RefCell};
1+
use std::cell::RefCell;
2+
use std::collections::{HashMap, hash_map::Entry};
3+
use std::cmp::max;
24

35
use rand::Rng;
46

5-
use rustc::mir::interpret::{AllocId, Pointer, InterpResult};
6-
use rustc_mir::interpret::Memory;
7+
use rustc_mir::interpret::{AllocId, Pointer, InterpResult, Memory, AllocCheck};
78
use rustc_target::abi::Size;
89

910
use crate::{Evaluator, Tag, STACK_ADDR};
1011

1112
pub type MemoryExtra = RefCell<GlobalState>;
1213

13-
#[derive(Clone, Debug, Default)]
14-
pub struct AllocExtra {
15-
base_addr: Cell<Option<u64>>
16-
}
17-
1814
#[derive(Clone, Debug)]
1915
pub struct GlobalState {
2016
/// This is used as a map between the address of each allocation and its `AllocId`.
2117
/// It is always sorted
2218
pub int_to_ptr_map: Vec<(u64, AllocId)>,
19+
/// The base address for each allocation. We cannot put that into
20+
/// `AllocExtra` because function pointers also have a base address, and
21+
/// they do not have an `AllocExtra`.
22+
/// This is the inverse of `int_to_ptr_map`.
23+
pub base_addr: HashMap<AllocId, u64>,
2324
/// This is used as a memory address when a new pointer is casted to an integer. It
2425
/// is always larger than any address that was previously made part of a block.
2526
pub next_base_addr: u64,
@@ -29,6 +30,7 @@ impl Default for GlobalState {
2930
fn default() -> Self {
3031
GlobalState {
3132
int_to_ptr_map: Vec::default(),
33+
base_addr: HashMap::default(),
3234
next_base_addr: STACK_ADDR,
3335
}
3436
}
@@ -71,13 +73,13 @@ impl<'mir, 'tcx> GlobalState {
7173
memory: &Memory<'mir, 'tcx, Evaluator<'tcx>>,
7274
) -> InterpResult<'tcx, u64> {
7375
let mut global_state = memory.extra.intptrcast.borrow_mut();
76+
let global_state = &mut *global_state;
7477

75-
let alloc = memory.get(ptr.alloc_id)?;
76-
let align = alloc.align.bytes();
78+
let (size, align) = memory.get_size_and_align(ptr.alloc_id, AllocCheck::Live)?;
7779

78-
let base_addr = match alloc.extra.intptrcast.base_addr.get() {
79-
Some(base_addr) => base_addr,
80-
None => {
80+
let base_addr = match global_state.base_addr.entry(ptr.alloc_id) {
81+
Entry::Occupied(entry) => *entry.get(),
82+
Entry::Vacant(entry) => {
8183
// This allocation does not have a base address yet, pick one.
8284
// Leave some space to the previous allocation, to give it some chance to be less aligned.
8385
let slack = {
@@ -86,11 +88,12 @@ impl<'mir, 'tcx> GlobalState {
8688
rng.gen_range(0, 16)
8789
};
8890
// From next_base_addr + slack, round up to adjust for alignment.
89-
let base_addr = Self::align_addr(global_state.next_base_addr + slack, align);
90-
alloc.extra.intptrcast.base_addr.set(Some(base_addr));
91+
let base_addr = Self::align_addr(global_state.next_base_addr + slack, align.bytes());
92+
entry.insert(base_addr);
9193

92-
// Remember next base address.
93-
global_state.next_base_addr = base_addr + alloc.bytes.len() as u64;
94+
// Remember next base address. If this allocation is zero-sized, leave a gap
95+
// of at least 1 to avoid two allocations having the same base address.
96+
global_state.next_base_addr = base_addr + max(size.bytes(), 1);
9497
// Given that `next_base_addr` increases in each allocation, pushing the
9598
// corresponding tuple keeps `int_to_ptr_map` sorted
9699
global_state.int_to_ptr_map.push((base_addr, ptr.alloc_id));
@@ -99,7 +102,7 @@ impl<'mir, 'tcx> GlobalState {
99102
}
100103
};
101104

102-
debug_assert_eq!(base_addr % align, 0); // sanity check
105+
debug_assert_eq!(base_addr % align.bytes(), 0); // sanity check
103106
Ok(base_addr + ptr.offset.bytes())
104107
}
105108

src/machine.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ impl Into<MemoryKind<MiriMemoryKind>> for MiriMemoryKind {
4242
#[derive(Debug, Clone)]
4343
pub struct AllocExtra {
4444
pub stacked_borrows: stacked_borrows::AllocExtra,
45-
pub intptrcast: intptrcast::AllocExtra,
4645
}
4746

4847
/// Extra global memory data
@@ -277,7 +276,6 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
277276
mutability: alloc.mutability,
278277
extra: AllocExtra {
279278
stacked_borrows: stacks,
280-
intptrcast: Default::default(),
281279
},
282280
};
283281
(Cow::Owned(alloc), base_tag)

tests/run-pass/intptrcast_format.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// compile-flags: -Zmiri-seed=
2+
3+
fn main() {
4+
println!("Hello {}", 13);
5+
println!("{:0<width$}", "hello", width = 10);
6+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Hello 13
2+
hello00000

0 commit comments

Comments
 (0)