@@ -535,48 +535,52 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
535
535
id: AllocId,
536
536
liveness: AllocCheck,
537
537
) -> InterpResult<'static, (Size, Align)> {
538
+ // # Regular allocations
538
539
// Don't use `self.get` here as that will
539
540
// a) cause cycles in case `id` refers to a static
540
541
// 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
- },
578
- }
579
- }
542
+ if let Some((_, alloc)) = self.alloc_map.get(id) {
543
+ return Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align));
544
+ }
545
+
546
+ // # Function pointers
547
+ // (both global from `alloc_map` and local from `extra_fn_ptr_map`)
548
+ if let Ok(_) = self.get_fn_alloc(id) {
549
+ return if let AllocCheck::Dereferencable = liveness {
550
+ // The caller requested no function pointers.
551
+ err!(DerefFunctionPointer)
552
+ } else {
553
+ Ok((Size::ZERO, Align::from_bytes(1).unwrap()))
554
+ };
555
+ }
556
+
557
+ // # Statics
558
+ // Can't do this in the match argument, we may get cycle errors since the lock would
559
+ // be held throughout the match.
560
+ let alloc = self.tcx.alloc_map.lock().get(id);
561
+ match alloc {
562
+ Some(GlobalAlloc::Static(did)) => {
563
+ // Use size and align of the type.
564
+ let ty = self.tcx.type_of(did);
565
+ let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap();
566
+ Ok((layout.size, layout.align.abi))
567
+ },
568
+ Some(GlobalAlloc::Memory(alloc)) =>
569
+ // Need to duplicate the logic here, because the global allocations have
570
+ // different associated types than the interpreter-local ones.
571
+ Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align)),
572
+ Some(GlobalAlloc::Function(_)) =>
573
+ bug!("We already checked function pointers above"),
574
+ // The rest must be dead.
575
+ None => if let AllocCheck::MaybeDead = liveness {
576
+ // Deallocated pointers are allowed, we should be able to find
577
+ // them in the map.
578
+ Ok(*self.dead_alloc_map.get(&id)
579
+ .expect("deallocated pointers should all be recorded in \
580
+ `dead_alloc_map`"))
581
+ } else {
582
+ err!(DanglingPointerDeref)
583
+ },
580
584
}
581
585
}
582
586
0 commit comments