Skip to content

Commit 828e7b6

Browse files
committed
miri: add get and get_mut to AllocMap; use that in get_size_and_align and avoid rightwards drift
1 parent 9a239ef commit 828e7b6

File tree

2 files changed

+52
-38
lines changed

2 files changed

+52
-38
lines changed

src/librustc_mir/interpret/machine.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,22 @@ pub trait AllocMap<K: Hash + Eq, V> {
5454
k: K,
5555
vacant: impl FnOnce() -> Result<V, E>
5656
) -> Result<&mut V, E>;
57+
58+
/// Read-only lookup.
59+
fn get(&self, k: K) -> Option<&V> {
60+
match self.get_or(k, || Err(())) {
61+
Ok(v) => Some(v),
62+
Err(()) => None,
63+
}
64+
}
65+
66+
/// Mutable lookup.
67+
fn get_mut(&mut self, k: K) -> Option<&mut V> {
68+
match self.get_mut_or(k, || Err(())) {
69+
Ok(v) => Some(v),
70+
Err(()) => None,
71+
}
72+
}
5773
}
5874

5975
/// Methods of this trait signifies a point where CTFE evaluation would fail

src/librustc_mir/interpret/memory.rs

Lines changed: 36 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -538,45 +538,43 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
538538
// Don't use `self.get` here as that will
539539
// a) cause cycles in case `id` refers to a static
540540
// b) duplicate a static's allocation in miri
541-
match self.alloc_map.get_or(id, || Err(())) {
542-
Ok((_, alloc)) => Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align)),
543-
Err(()) => {
544-
// Not a local allocation, check the global `tcx.alloc_map`.
545-
546-
// Can't do this in the match argument, we may get cycle errors since the lock would
547-
// be held throughout the match.
548-
let alloc = self.tcx.alloc_map.lock().get(id);
549-
match alloc {
550-
Some(GlobalAlloc::Static(did)) => {
551-
// Use size and align of the type.
552-
let ty = self.tcx.type_of(did);
553-
let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap();
554-
Ok((layout.size, layout.align.abi))
555-
},
556-
Some(GlobalAlloc::Memory(alloc)) =>
557-
// Need to duplicate the logic here, because the global allocations have
558-
// different associated types than the interpreter-local ones.
559-
Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align)),
560-
Some(GlobalAlloc::Function(_)) => {
561-
if let AllocCheck::Dereferencable = liveness {
562-
// The caller requested no function pointers.
563-
err!(DerefFunctionPointer)
564-
} else {
565-
Ok((Size::ZERO, Align::from_bytes(1).unwrap()))
566-
}
567-
},
568-
// The rest must be dead.
569-
None => if let AllocCheck::MaybeDead = liveness {
570-
// Deallocated pointers are allowed, we should be able to find
571-
// them in the map.
572-
Ok(*self.dead_alloc_map.get(&id)
573-
.expect("deallocated pointers should all be recorded in \
574-
`dead_alloc_map`"))
575-
} else {
576-
err!(DanglingPointerDeref)
577-
},
541+
if let Some((_, alloc)) = self.alloc_map.get(id) {
542+
return Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align));
543+
}
544+
// Not a local allocation, check the global `tcx.alloc_map`.
545+
546+
// Can't do this in the match argument, we may get cycle errors since the lock would
547+
// be held throughout the match.
548+
let alloc = self.tcx.alloc_map.lock().get(id);
549+
match alloc {
550+
Some(GlobalAlloc::Static(did)) => {
551+
// Use size and align of the type.
552+
let ty = self.tcx.type_of(did);
553+
let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap();
554+
Ok((layout.size, layout.align.abi))
555+
},
556+
Some(GlobalAlloc::Memory(alloc)) =>
557+
// Need to duplicate the logic here, because the global allocations have
558+
// different associated types than the interpreter-local ones.
559+
Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align)),
560+
Some(GlobalAlloc::Function(_)) => {
561+
if let AllocCheck::Dereferencable = liveness {
562+
// The caller requested no function pointers.
563+
err!(DerefFunctionPointer)
564+
} else {
565+
Ok((Size::ZERO, Align::from_bytes(1).unwrap()))
578566
}
579-
}
567+
},
568+
// The rest must be dead.
569+
None => if let AllocCheck::MaybeDead = liveness {
570+
// Deallocated pointers are allowed, we should be able to find
571+
// them in the map.
572+
Ok(*self.dead_alloc_map.get(&id)
573+
.expect("deallocated pointers should all be recorded in \
574+
`dead_alloc_map`"))
575+
} else {
576+
err!(DanglingPointerDeref)
577+
},
580578
}
581579
}
582580

0 commit comments

Comments
 (0)