give machine more control over what counts as memory leak

This commit is contained in:
Ralf Jung 2018-10-16 12:45:44 +02:00
parent 21934c81f4
commit 5b7185794f
4 changed files with 28 additions and 10 deletions

View File

@ -333,6 +333,14 @@ fn get_mut_or<E>(
type CompileTimeEvalContext<'a, 'mir, 'tcx> =
EvalContext<'a, 'mir, 'tcx, CompileTimeInterpreter<'a, 'mir, 'tcx>>;
impl interpret::MayLeak for ! {
#[inline(always)]
fn may_leak(self) -> bool {
// `self` is uninhabited
self
}
}
impl<'a, 'mir, 'tcx> interpret::Machine<'a, 'mir, 'tcx>
for CompileTimeInterpreter<'a, 'mir, 'tcx>
{

View File

@ -22,6 +22,11 @@
use super::{EvalContext, PlaceTy, OpTy, MemoryKind};
/// Whether this kind of memory is allowed to leak
pub trait MayLeak: Copy {
fn may_leak(self) -> bool;
}
/// The functionality needed by memory to manage its allocations
pub trait AllocMap<K: Hash + Eq, V> {
/// Test if the map contains the given key.
@ -63,7 +68,7 @@ fn get_mut_or<E>(
/// and some use case dependent behaviour can instead be applied.
pub trait Machine<'a, 'mir, 'tcx>: Sized {
/// Additional memory kinds a machine wishes to distinguish from the builtin ones
type MemoryKinds: ::std::fmt::Debug + Copy + Eq + 'static;
type MemoryKinds: ::std::fmt::Debug + MayLeak + Eq + 'static;
/// Tag tracked alongside every pointer. This is used to implement "Stacked Borrows"
/// <https://www.ralfj.de/blog/2018/08/07/stacked-borrows.html>.

View File

@ -32,7 +32,7 @@
use syntax::ast::Mutability;
use super::{Machine, AllocMap, ScalarMaybeUndef};
use super::{Machine, AllocMap, MayLeak, ScalarMaybeUndef};
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
pub enum MemoryKind<T> {
@ -44,6 +44,17 @@ pub enum MemoryKind<T> {
Machine(T),
}
impl<T: MayLeak> MayLeak for MemoryKind<T> {
#[inline]
fn may_leak(self) -> bool {
match self {
MemoryKind::Stack => false,
MemoryKind::Vtable => true,
MemoryKind::Machine(k) => k.may_leak()
}
}
}
// `Memory` has to depend on the `Machine` because some of its operations
// (e.g. `get`) call a `Machine` hook.
pub struct Memory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'a, 'mir, 'tcx>> {
@ -584,13 +595,7 @@ pub fn dump_allocs(&self, mut allocs: Vec<AllocId>) {
pub fn leak_report(&self) -> usize {
trace!("### LEAK REPORT ###");
let leaks: Vec<_> = self.alloc_map.filter_map_collect(|&id, &(kind, _)| {
// exclude statics and vtables
let exclude = match kind {
MemoryKind::Stack => false,
MemoryKind::Vtable => true,
MemoryKind::Machine(k) => Some(k) == M::STATIC_KIND,
};
if exclude { None } else { Some(id) }
if kind.may_leak() { None } else { Some(id) }
});
let n = leaks.len();
self.dump_allocs(leaks);

View File

@ -32,7 +32,7 @@
pub use self::memory::{Memory, MemoryKind};
pub use self::machine::{Machine, AllocMap};
pub use self::machine::{Machine, AllocMap, MayLeak};
pub use self::operand::{ScalarMaybeUndef, Value, ValTy, Operand, OpTy};