diff options
| author | Oliver Scherer <github35764891676564198441@oli-obk.de> | 2019-07-26 10:34:54 +0200 |
|---|---|---|
| committer | Oliver Scherer <github35764891676564198441@oli-obk.de> | 2019-07-26 10:34:54 +0200 |
| commit | 3bc1d01bb9d81fa3682186d8ace06becaa8cac8c (patch) | |
| tree | f651baf3d2c168e46a2c286a40189a09576ac1b5 | |
| parent | 34e7a3cc4dcb7ddd404b9566047a78d1e234f137 (diff) | |
| download | rust-3bc1d01bb9d81fa3682186d8ace06becaa8cac8c.tar.gz rust-3bc1d01bb9d81fa3682186d8ace06becaa8cac8c.zip | |
Clear up `get_size_and_align`
| -rw-r--r-- | src/librustc_mir/interpret/memory.rs | 71 |
1 files changed, 37 insertions, 34 deletions
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 4ac5920c60e..9140c90bed3 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -535,41 +535,44 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { id: AllocId, liveness: AllocCheck, ) -> InterpResult<'static, (Size, Align)> { - let alloc_or_size_align = self.alloc_map.get_or(id, || { - // 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); - Err(match alloc { - Some(GlobalAlloc::Static(did)) => { - // Use size and align of the type - let ty = self.tcx.type_of(did); - let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap(); - Ok((layout.size, layout.align.abi)) - }, - Some(GlobalAlloc::Memory(alloc)) => - // this duplicates the logic on the `match alloc_or_size_align`, but due to the - // API of `get_or` there's no way around that. - 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())) - }, - // The rest must be dead. - None => if let AllocCheck::MaybeDead = liveness { - // Deallocated pointers are allowed, we should be able to find - // them in the map. - Ok(*self.dead_alloc_map.get(&id) - .expect("deallocated pointers should all be recorded in `dead_alloc_map`")) - } else { - err!(DanglingPointerDeref) - }, - }) - }); - match alloc_or_size_align { + // 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 + match self.alloc_map.get_or(id, || Err(())) { Ok((_, alloc)) => Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align)), - Err(done) => done, + Err(()) => { + // 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); + match alloc { + Some(GlobalAlloc::Static(did)) => { + // Use size and align of the type + let ty = self.tcx.type_of(did); + let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap(); + return Ok((layout.size, layout.align.abi)); + }, + Some(GlobalAlloc::Memory(alloc)) => + // 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. + return err!(DerefFunctionPointer); + } else { + return Ok((Size::ZERO, Align::from_bytes(1).unwrap())); + }, + // The rest must be dead. + None => return if let AllocCheck::MaybeDead = liveness { + // Deallocated pointers are allowed, we should be able to find + // them in the map. + Ok(*self.dead_alloc_map.get(&id) + .expect("deallocated pointers should all be recorded in \ + `dead_alloc_map`")) + } else { + err!(DanglingPointerDeref) + }, + } + } } } |
