diff options
| author | Ralf Jung <post@ralfj.de> | 2019-07-28 13:02:01 +0200 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2019-07-28 13:26:28 +0200 |
| commit | c119291b55f2a14a2b0e13fbd3d54a9692f1066f (patch) | |
| tree | 088eafcd2c09adcaf8a45217c920e266351ac848 | |
| parent | 828e7b685ade9d53a8f72f3509a98f2255787136 (diff) | |
| download | rust-c119291b55f2a14a2b0e13fbd3d54a9692f1066f.tar.gz rust-c119291b55f2a14a2b0e13fbd3d54a9692f1066f.zip | |
get_size_and_align: fix handling of function pointers
| -rw-r--r-- | src/librustc_mir/interpret/memory.rs | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 12be9baec13..87dd7738410 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -535,14 +535,26 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { id: AllocId, liveness: AllocCheck, ) -> InterpResult<'static, (Size, Align)> { + // # Regular allocations // Don't use `self.get` here as that will // a) cause cycles in case `id` refers to a static // b) duplicate a static's allocation in miri if let Some((_, alloc)) = self.alloc_map.get(id) { return Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align)); } - // Not a local allocation, check the global `tcx.alloc_map`. + // # Function pointers + // (both global from `alloc_map` and local from `extra_fn_ptr_map`) + if let Ok(_) = self.get_fn_alloc(id) { + return if let AllocCheck::Dereferencable = liveness { + // The caller requested no function pointers. + err!(DerefFunctionPointer) + } else { + Ok((Size::ZERO, Align::from_bytes(1).unwrap())) + }; + } + + // # Statics // Can't do this in the match argument, we may get cycle errors since the lock would // be held throughout the match. let alloc = self.tcx.alloc_map.lock().get(id); @@ -557,14 +569,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // Need to duplicate the logic here, because the global allocations have // different associated types than the interpreter-local ones. Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align)), - Some(GlobalAlloc::Function(_)) => { - if let AllocCheck::Dereferencable = liveness { - // The caller requested no function pointers. - err!(DerefFunctionPointer) - } else { - Ok((Size::ZERO, Align::from_bytes(1).unwrap())) - } - }, + Some(GlobalAlloc::Function(_)) => + bug!("We already checked function pointers above"), // The rest must be dead. None => if let AllocCheck::MaybeDead = liveness { // Deallocated pointers are allowed, we should be able to find |
