Skip to content

Commit c9039de

Browse files
committed
Auto merge of #2071 - RalfJung:provenance, r=RalfJung
adjust for provenance cleanup This is the Miri side of rust-lang/rust#96165
2 parents 598ae74 + b5a76c7 commit c9039de

File tree

9 files changed

+92
-49
lines changed

9 files changed

+92
-49
lines changed

rust-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
c8422403f775126c40d558838d321c063554c822
1+
27af5175497936ea3413bef5816e7c0172514b9c

src/data_race.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -999,15 +999,15 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriEvalContextExt<'mir, 'tcx> {
999999
if let Some(data_race) = &this.machine.data_race {
10001000
if data_race.multi_threaded.get() {
10011001
let size = place.layout.size;
1002-
let (alloc_id, base_offset, ptr) = this.ptr_get_alloc_id(place.ptr)?;
1002+
let (alloc_id, base_offset, _tag) = this.ptr_get_alloc_id(place.ptr)?;
10031003
// Load and log the atomic operation.
10041004
// Note that atomic loads are possible even from read-only allocations, so `get_alloc_extra_mut` is not an option.
10051005
let alloc_meta = &this.get_alloc_extra(alloc_id)?.data_race.as_ref().unwrap();
10061006
log::trace!(
10071007
"Atomic op({}) with ordering {:?} on {:?} (size={})",
10081008
description,
10091009
&atomic,
1010-
ptr,
1010+
place.ptr,
10111011
size.bytes()
10121012
);
10131013

@@ -1039,7 +1039,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriEvalContextExt<'mir, 'tcx> {
10391039
{
10401040
log::trace!(
10411041
"Updated atomic memory({:?}, size={}) to {:#?}",
1042-
ptr,
1042+
place.ptr,
10431043
size.bytes(),
10441044
range.atomic_ops
10451045
);

src/helpers.rs

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -271,8 +271,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
271271
/// Visits the memory covered by `place`, sensitive to freezing: the 2nd parameter
272272
/// of `action` will be true if this is frozen, false if this is in an `UnsafeCell`.
273273
/// The range is relative to `place`.
274-
///
275-
/// Assumes that the `place` has a proper pointer in it.
276274
fn visit_freeze_sensitive(
277275
&self,
278276
place: &MPlaceTy<'tcx, Tag>,
@@ -290,33 +288,30 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
290288
// Store how far we proceeded into the place so far. Everything to the left of
291289
// this offset has already been handled, in the sense that the frozen parts
292290
// have had `action` called on them.
293-
let ptr = place.ptr.into_pointer_or_addr().unwrap();
294-
let start_offset = ptr.into_parts().1 as Size; // we just compare offsets, the abs. value never matters
295-
let mut cur_offset = start_offset;
291+
let start_addr = place.ptr.addr();
292+
let mut cur_addr = start_addr;
296293
// Called when we detected an `UnsafeCell` at the given offset and size.
297294
// Calls `action` and advances `cur_ptr`.
298-
let mut unsafe_cell_action = |unsafe_cell_ptr: Pointer<Option<Tag>>,
295+
let mut unsafe_cell_action = |unsafe_cell_ptr: &Pointer<Option<Tag>>,
299296
unsafe_cell_size: Size| {
300-
let unsafe_cell_ptr = unsafe_cell_ptr.into_pointer_or_addr().unwrap();
301-
debug_assert_eq!(unsafe_cell_ptr.provenance, ptr.provenance);
302297
// We assume that we are given the fields in increasing offset order,
303298
// and nothing else changes.
304-
let unsafe_cell_offset = unsafe_cell_ptr.into_parts().1 as Size; // we just compare offsets, the abs. value never matters
305-
assert!(unsafe_cell_offset >= cur_offset);
306-
let frozen_size = unsafe_cell_offset - cur_offset;
299+
let unsafe_cell_addr = unsafe_cell_ptr.addr();
300+
assert!(unsafe_cell_addr >= cur_addr);
301+
let frozen_size = unsafe_cell_addr - cur_addr;
307302
// Everything between the cur_ptr and this `UnsafeCell` is frozen.
308303
if frozen_size != Size::ZERO {
309-
action(alloc_range(cur_offset - start_offset, frozen_size), /*frozen*/ true)?;
304+
action(alloc_range(cur_addr - start_addr, frozen_size), /*frozen*/ true)?;
310305
}
311-
cur_offset += frozen_size;
306+
cur_addr += frozen_size;
312307
// This `UnsafeCell` is NOT frozen.
313308
if unsafe_cell_size != Size::ZERO {
314309
action(
315-
alloc_range(cur_offset - start_offset, unsafe_cell_size),
310+
alloc_range(cur_addr - start_addr, unsafe_cell_size),
316311
/*frozen*/ false,
317312
)?;
318313
}
319-
cur_offset += unsafe_cell_size;
314+
cur_addr += unsafe_cell_size;
320315
// Done
321316
Ok(())
322317
};
@@ -334,7 +329,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
334329
.unwrap_or_else(|| place.layout.size);
335330
// Now handle this `UnsafeCell`, unless it is empty.
336331
if unsafe_cell_size != Size::ZERO {
337-
unsafe_cell_action(place.ptr, unsafe_cell_size)
332+
unsafe_cell_action(&place.ptr, unsafe_cell_size)
338333
} else {
339334
Ok(())
340335
}
@@ -344,7 +339,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
344339
}
345340
// The part between the end_ptr and the end of the place is also frozen.
346341
// So pretend there is a 0-sized `UnsafeCell` at the end.
347-
unsafe_cell_action(place.ptr.wrapping_offset(size, this), Size::ZERO)?;
342+
unsafe_cell_action(&place.ptr.offset(size, this)?, Size::ZERO)?;
348343
// Done!
349344
return Ok(());
350345

@@ -428,9 +423,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
428423
let mut places =
429424
fields.collect::<InterpResult<'tcx, Vec<MPlaceTy<'tcx, Tag>>>>()?;
430425
// we just compare offsets, the abs. value never matters
431-
places.sort_by_key(|place| {
432-
place.ptr.into_pointer_or_addr().unwrap().into_parts().1 as Size
433-
});
426+
places.sort_by_key(|place| place.ptr.addr());
434427
self.walk_aggregate(place, places.into_iter().map(Ok))
435428
}
436429
FieldsShape::Union { .. } | FieldsShape::Primitive => {
@@ -777,6 +770,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
777770
/// Mark a machine allocation that was just created as immutable.
778771
fn mark_immutable(&mut self, mplace: &MemPlace<Tag>) {
779772
let this = self.eval_context_mut();
773+
// This got just allocated, so there definitely is a pointer here.
780774
this.alloc_mark_immutable(mplace.ptr.into_pointer_or_addr().unwrap().provenance.alloc_id)
781775
.unwrap();
782776
}

src/intptrcast.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ impl<'mir, 'tcx> GlobalStateInner {
128128

129129
/// Convert a relative (tcx) pointer to an absolute address.
130130
pub fn rel_ptr_to_addr(ecx: &MiriEvalContext<'mir, 'tcx>, ptr: Pointer<AllocId>) -> u64 {
131-
let (alloc_id, offset) = ptr.into_parts(); // offset is relative
131+
let (alloc_id, offset) = ptr.into_parts(); // offset is relative (AllocId provenance)
132132
let base_addr = GlobalStateInner::alloc_base_addr(ecx, alloc_id);
133133

134134
// Add offset with the right kind of pointer-overflowing arithmetic.
@@ -137,7 +137,7 @@ impl<'mir, 'tcx> GlobalStateInner {
137137
}
138138

139139
pub fn abs_ptr_to_rel(ecx: &MiriEvalContext<'mir, 'tcx>, ptr: Pointer<Tag>) -> Size {
140-
let (tag, addr) = ptr.into_parts(); // addr is absolute
140+
let (tag, addr) = ptr.into_parts(); // addr is absolute (Tag provenance)
141141
let base_addr = GlobalStateInner::alloc_base_addr(ecx, tag.alloc_id);
142142

143143
// Wrapping "addr - base_addr"

src/machine.rs

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,7 @@ impl<'mir, 'tcx> Evaluator<'mir, 'tcx> {
360360
name: &str,
361361
ptr: Pointer<Option<Tag>>,
362362
) {
363+
// This got just allocated, so there definitely is a pointer here.
363364
let ptr = ptr.into_pointer_or_addr().unwrap();
364365
this.machine.extern_statics.try_insert(Symbol::intern(name), ptr).unwrap();
365366
}
@@ -431,11 +432,13 @@ impl<'mir, 'tcx> MiriEvalContextExt<'mir, 'tcx> for MiriEvalContext<'mir, 'tcx>
431432
/// Machine hook implementations.
432433
impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
433434
type MemoryKind = MiriMemoryKind;
435+
type ExtraFnVal = Dlsym;
434436

435437
type FrameExtra = FrameData<'tcx>;
436438
type AllocExtra = AllocExtra;
439+
437440
type PointerTag = Tag;
438-
type ExtraFnVal = Dlsym;
441+
type TagExtra = SbTag;
439442

440443
type MemoryMap =
441444
MonoHashMap<AllocId, (MemoryKind<MiriMemoryKind>, Allocation<Tag, Self::AllocExtra>)>;
@@ -607,26 +610,26 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
607610
fn ptr_get_alloc(
608611
ecx: &MiriEvalContext<'mir, 'tcx>,
609612
ptr: Pointer<Self::PointerTag>,
610-
) -> (AllocId, Size) {
613+
) -> (AllocId, Size, Self::TagExtra) {
611614
let rel = intptrcast::GlobalStateInner::abs_ptr_to_rel(ecx, ptr);
612-
(ptr.provenance.alloc_id, rel)
615+
(ptr.provenance.alloc_id, rel, ptr.provenance.sb)
613616
}
614617

615618
#[inline(always)]
616619
fn memory_read(
617620
_tcx: TyCtxt<'tcx>,
618621
machine: &Self,
619622
alloc_extra: &AllocExtra,
620-
tag: Tag,
623+
(alloc_id, tag): (AllocId, Self::TagExtra),
621624
range: AllocRange,
622625
) -> InterpResult<'tcx> {
623626
if let Some(data_race) = &alloc_extra.data_race {
624-
data_race.read(tag.alloc_id, range, machine.data_race.as_ref().unwrap())?;
627+
data_race.read(alloc_id, range, machine.data_race.as_ref().unwrap())?;
625628
}
626629
if let Some(stacked_borrows) = &alloc_extra.stacked_borrows {
627630
stacked_borrows.memory_read(
628-
tag.alloc_id,
629-
tag.sb,
631+
alloc_id,
632+
tag,
630633
range,
631634
machine.stacked_borrows.as_ref().unwrap(),
632635
)
@@ -640,16 +643,16 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
640643
_tcx: TyCtxt<'tcx>,
641644
machine: &mut Self,
642645
alloc_extra: &mut AllocExtra,
643-
tag: Tag,
646+
(alloc_id, tag): (AllocId, Self::TagExtra),
644647
range: AllocRange,
645648
) -> InterpResult<'tcx> {
646649
if let Some(data_race) = &mut alloc_extra.data_race {
647-
data_race.write(tag.alloc_id, range, machine.data_race.as_mut().unwrap())?;
650+
data_race.write(alloc_id, range, machine.data_race.as_mut().unwrap())?;
648651
}
649652
if let Some(stacked_borrows) = &mut alloc_extra.stacked_borrows {
650653
stacked_borrows.memory_written(
651-
tag.alloc_id,
652-
tag.sb,
654+
alloc_id,
655+
tag,
653656
range,
654657
machine.stacked_borrows.as_mut().unwrap(),
655658
)
@@ -663,19 +666,19 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
663666
_tcx: TyCtxt<'tcx>,
664667
machine: &mut Self,
665668
alloc_extra: &mut AllocExtra,
666-
tag: Tag,
669+
(alloc_id, tag): (AllocId, Self::TagExtra),
667670
range: AllocRange,
668671
) -> InterpResult<'tcx> {
669-
if Some(tag.alloc_id) == machine.tracked_alloc_id {
670-
register_diagnostic(NonHaltingDiagnostic::FreedAlloc(tag.alloc_id));
672+
if Some(alloc_id) == machine.tracked_alloc_id {
673+
register_diagnostic(NonHaltingDiagnostic::FreedAlloc(alloc_id));
671674
}
672675
if let Some(data_race) = &mut alloc_extra.data_race {
673-
data_race.deallocate(tag.alloc_id, range, machine.data_race.as_mut().unwrap())?;
676+
data_race.deallocate(alloc_id, range, machine.data_race.as_mut().unwrap())?;
674677
}
675678
if let Some(stacked_borrows) = &mut alloc_extra.stacked_borrows {
676679
stacked_borrows.memory_deallocated(
677-
tag.alloc_id,
678-
tag.sb,
680+
alloc_id,
681+
tag,
679682
range,
680683
machine.stacked_borrows.as_mut().unwrap(),
681684
)

src/shims/backtrace.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
124124

125125
let ptr = this.read_pointer(ptr)?;
126126
// Take apart the pointer, we need its pieces.
127-
let (alloc_id, offset, ptr) = this.ptr_get_alloc_id(ptr)?;
127+
let (alloc_id, offset, _tag) = this.ptr_get_alloc_id(ptr)?;
128128

129129
let fn_instance =
130130
if let Some(GlobalAlloc::Function(instance)) = this.tcx.get_global_alloc(alloc_id) {

src/shims/mod.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
8383
}
8484

8585
let ptr = this.read_pointer(ptr_op)?;
86-
if let Ok(ptr) = ptr.into_pointer_or_addr() {
86+
if let Ok((alloc_id, _offset, _)) = this.ptr_try_get_alloc_id(ptr) {
8787
// Only do anything if we can identify the allocation this goes to.
88-
let (_, cur_align) =
89-
this.get_alloc_size_and_align(ptr.provenance.alloc_id, AllocCheck::MaybeDead)?;
88+
let (_, cur_align) = this.get_alloc_size_and_align(alloc_id, AllocCheck::MaybeDead)?;
9089
if cur_align.bytes() >= req_align {
9190
// If the allocation alignment is at least the required alignment we use the
9291
// real implementation.

src/stacked_borrows.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -702,8 +702,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
702702
);
703703
return Ok(());
704704
}
705-
let (alloc_id, base_offset, ptr) = this.ptr_get_alloc_id(place.ptr)?;
706-
let orig_tag = ptr.provenance.sb;
705+
let (alloc_id, base_offset, orig_tag) = this.ptr_get_alloc_id(place.ptr)?;
707706

708707
// Ensure we bail out if the pointer goes out-of-bounds (see miri#1050).
709708
let (alloc_size, _) =

tests/run-pass/issue-miri-2068.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#![feature(pin_macro)]
2+
3+
use core::future::Future;
4+
use core::pin::Pin;
5+
use core::task::{Context, Poll};
6+
7+
use std::sync::Arc;
8+
9+
struct NopWaker;
10+
11+
impl std::task::Wake for NopWaker {
12+
fn wake(self: Arc<Self>) {}
13+
}
14+
15+
pub fn fuzzing_block_on<O, F: Future<Output = O>>(fut: F) -> O {
16+
let mut fut = std::pin::pin!(fut);
17+
let waker = std::task::Waker::from(Arc::new(NopWaker));
18+
let mut context = std::task::Context::from_waker(&waker);
19+
loop {
20+
match fut.as_mut().poll(&mut context) {
21+
Poll::Ready(v) => return v,
22+
Poll::Pending => {}
23+
}
24+
}
25+
}
26+
27+
pub struct LastFuture<S> {
28+
last: S,
29+
}
30+
31+
impl<S> Future for LastFuture<S>
32+
where
33+
Self: Unpin,
34+
S: Unpin + Copy,
35+
{
36+
type Output = S;
37+
38+
fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
39+
return Poll::Ready(self.last);
40+
}
41+
}
42+
43+
fn main() {
44+
fuzzing_block_on(async {
45+
LastFuture { last: &0u32 }.await;
46+
LastFuture { last: Option::<u32>::None }.await;
47+
});
48+
}

0 commit comments

Comments
 (0)