Skip to content

Commit 66e995f

Browse files
committed
Fix behavior of transmuting pointers
1 parent f4a7e05 commit 66e995f

File tree

3 files changed

+29
-18
lines changed

3 files changed

+29
-18
lines changed

src/intptrcast.rs

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ impl<'mir, 'tcx> GlobalStateInner {
4848
// or `None` if the addr is out of bounds
4949
fn alloc_id_from_addr(ecx: &MiriEvalContext<'mir, 'tcx>, addr: u64) -> Option<AllocId> {
5050
let global_state = ecx.machine.intptrcast.borrow();
51-
assert!(global_state.provenance_mode != ProvenanceMode::Strict);
5251

5352
let pos = global_state.int_to_ptr_map.binary_search_by_key(&addr, |(addr, _)| *addr);
5453

@@ -77,30 +76,43 @@ impl<'mir, 'tcx> GlobalStateInner {
7776
}
7877
}?;
7978

80-
match global_state.provenance_mode {
81-
ProvenanceMode::Legacy => Some(alloc_id),
82-
ProvenanceMode::Permissive if global_state.exposed.contains(&alloc_id) =>
83-
Some(alloc_id),
84-
_ => None,
79+
// In legacy mode, we consider all allocations exposed.
80+
if global_state.provenance_mode == ProvenanceMode::Legacy
81+
|| global_state.exposed.contains(&alloc_id)
82+
{
83+
Some(alloc_id)
84+
} else {
85+
None
8586
}
8687
}
8788

8889
pub fn expose_addr(ecx: &MiriEvalContext<'mir, 'tcx>, alloc_id: AllocId) {
8990
trace!("Exposing allocation id {:?}", alloc_id);
9091

9192
let mut global_state = ecx.machine.intptrcast.borrow_mut();
92-
global_state.exposed.insert(alloc_id);
93+
if global_state.provenance_mode == ProvenanceMode::Permissive {
94+
global_state.exposed.insert(alloc_id);
95+
}
9396
}
9497

95-
pub fn ptr_from_addr(ecx: &MiriEvalContext<'mir, 'tcx>, addr: u64) -> Pointer<Option<Tag>> {
98+
pub fn ptr_from_addr_transmute(
99+
ecx: &MiriEvalContext<'mir, 'tcx>,
100+
addr: u64,
101+
) -> Pointer<Option<Tag>> {
96102
trace!("Transmuting 0x{:x} to a pointer", addr);
97103

98-
// TODO: fix this at some point once we deal with function pointers
99-
// Pointer::new(None, Size::from_bytes(addr))
100-
Self::ptr_from_casted_addr(ecx, addr)
104+
let global_state = ecx.machine.intptrcast.borrow();
105+
106+
// In legacy mode, we have to support int2ptr transmutes,
107+
// so just pretend they do the same thing as a cast.
108+
if global_state.provenance_mode == ProvenanceMode::Legacy {
109+
Self::ptr_from_addr_cast(ecx, addr)
110+
} else {
111+
Pointer::new(None, Size::from_bytes(addr))
112+
}
101113
}
102114

103-
pub fn ptr_from_casted_addr(
115+
pub fn ptr_from_addr_cast(
104116
ecx: &MiriEvalContext<'mir, 'tcx>,
105117
addr: u64,
106118
) -> Pointer<Option<Tag>> {

src/machine.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -639,15 +639,15 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
639639
ecx: &MiriEvalContext<'mir, 'tcx>,
640640
addr: u64,
641641
) -> Pointer<Option<Self::PointerTag>> {
642-
intptrcast::GlobalStateInner::ptr_from_addr(ecx, addr)
642+
intptrcast::GlobalStateInner::ptr_from_addr_cast(ecx, addr)
643643
}
644644

645645
#[inline(always)]
646646
fn ptr_from_addr_transmute(
647647
ecx: &MiriEvalContext<'mir, 'tcx>,
648648
addr: u64,
649649
) -> Pointer<Option<Self::PointerTag>> {
650-
Self::ptr_from_addr_cast(ecx, addr)
650+
intptrcast::GlobalStateInner::ptr_from_addr_transmute(ecx, addr)
651651
}
652652

653653
#[inline(always)]
@@ -675,8 +675,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
675675
) -> Option<(AllocId, Size, Self::TagExtra)> {
676676
let rel = intptrcast::GlobalStateInner::abs_ptr_to_rel(ecx, ptr);
677677

678-
let (tag, _) = ptr.into_parts();
679-
let sb = match tag {
678+
let sb = match ptr.provenance {
680679
Tag::Concrete(ConcreteTag { sb, .. }) => sb,
681680
Tag::Wildcard => SbTag::Untagged,
682681
};

tests/compile-fail/permissive_provenance_null.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// compile-flags: -Zmiri-permissive-provenance
1+
// compile-flags: -Zmiri-permissive-provenance -Zmiri-disable-stacked-borrows
22
#![feature(strict_provenance)]
33

44
use std::ptr;
@@ -9,6 +9,6 @@ fn main() {
99
let x_usize = x_ptr.expose_addr();
1010

1111
unsafe {
12-
let _a = *ptr::from_exposed_addr::<i32>(0).with_addr(x_usize); //~ ERROR attempting a read access using
12+
let _a = *ptr::from_exposed_addr::<i32>(0).with_addr(x_usize); //~ ERROR dereferencing pointer failed
1313
}
1414
}

0 commit comments

Comments
 (0)