give machine more control over what counts as memory leak
This commit is contained in:
parent
21934c81f4
commit
5b7185794f
@ -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>
|
||||
{
|
||||
|
@ -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>.
|
||||
|
@ -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);
|
||||
|
@ -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};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user