Provide better notes when tracking a pointer tag
This commit is contained in:
parent
e969615937
commit
cd6921923c
@ -7,6 +7,7 @@ use log::trace;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_span::{source_map::DUMMY_SP, Span, SpanData, Symbol};
|
||||
|
||||
use crate::stacked_borrows::{AccessKind, SbTag};
|
||||
use crate::*;
|
||||
|
||||
/// Details of premature program termination.
|
||||
@ -58,7 +59,9 @@ impl MachineStopType for TerminationInfo {}
|
||||
/// Miri specific diagnostics
|
||||
pub enum NonHaltingDiagnostic {
|
||||
CreatedPointerTag(NonZeroU64),
|
||||
PoppedPointerTag(Item),
|
||||
/// This `Item` was popped from the borrow stack, either due to a grant of
|
||||
/// `AccessKind` to `SbTag` or a deallocation when the second argument is `None`.
|
||||
PoppedPointerTag(Item, Option<(SbTag, AccessKind)>),
|
||||
CreatedCallId(CallId),
|
||||
CreatedAlloc(AllocId),
|
||||
FreedAlloc(AllocId),
|
||||
@ -321,7 +324,20 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
use NonHaltingDiagnostic::*;
|
||||
let msg = match e {
|
||||
CreatedPointerTag(tag) => format!("created tag {:?}", tag),
|
||||
PoppedPointerTag(item) => format!("popped tracked tag for item {:?}", item),
|
||||
PoppedPointerTag(item, tag) =>
|
||||
match tag {
|
||||
None =>
|
||||
format!(
|
||||
"popped tracked tag for item {:?} due to deallocation",
|
||||
item
|
||||
),
|
||||
Some((tag, access)) => {
|
||||
format!(
|
||||
"popped tracked tag for item {:?} due to {:?} access for {:?}",
|
||||
item, access, tag
|
||||
)
|
||||
}
|
||||
},
|
||||
CreatedCallId(id) => format!("function call with id {}", id),
|
||||
CreatedAlloc(AllocId(id)) => format!("created allocation with id {}", id),
|
||||
FreedAlloc(AllocId(id)) => format!("freed allocation with id {}", id),
|
||||
|
@ -111,7 +111,7 @@ pub struct GlobalState {
|
||||
pub type MemoryExtra = RefCell<GlobalState>;
|
||||
|
||||
/// Indicates which kind of access is being performed.
|
||||
#[derive(Copy, Clone, Hash, PartialEq, Eq)]
|
||||
#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)]
|
||||
pub enum AccessKind {
|
||||
Read,
|
||||
Write,
|
||||
@ -296,19 +296,26 @@ impl<'tcx> Stack {
|
||||
}
|
||||
|
||||
/// Check if the given item is protected.
|
||||
///
|
||||
/// The `provoking_access` argument is only used to produce diagnostics.
|
||||
/// It is `Some` when we are granting the contained access for said tag, and it is
|
||||
/// `None` during a deallocation.
|
||||
fn check_protector(
|
||||
item: &Item,
|
||||
tag: Option<SbTag>,
|
||||
provoking_access: Option<(SbTag, AccessKind)>,
|
||||
global: &GlobalState,
|
||||
) -> InterpResult<'tcx> {
|
||||
if let SbTag::Tagged(id) = item.tag {
|
||||
if Some(id) == global.tracked_pointer_tag {
|
||||
register_diagnostic(NonHaltingDiagnostic::PoppedPointerTag(item.clone()));
|
||||
register_diagnostic(NonHaltingDiagnostic::PoppedPointerTag(
|
||||
item.clone(),
|
||||
provoking_access,
|
||||
));
|
||||
}
|
||||
}
|
||||
if let Some(call) = item.protector {
|
||||
if global.is_active(call) {
|
||||
if let Some(tag) = tag {
|
||||
if let Some((tag, _)) = provoking_access {
|
||||
Err(err_sb_ub(format!(
|
||||
"not granting access to tag {:?} because incompatible item is protected: {:?}",
|
||||
tag, item
|
||||
@ -348,7 +355,7 @@ impl<'tcx> Stack {
|
||||
let first_incompatible_idx = self.find_first_write_incompatible(granting_idx);
|
||||
for item in self.borrows.drain(first_incompatible_idx..).rev() {
|
||||
trace!("access: popping item {:?}", item);
|
||||
Stack::check_protector(&item, Some(tag), global)?;
|
||||
Stack::check_protector(&item, Some((tag, access)), global)?;
|
||||
}
|
||||
} else {
|
||||
// On a read, *disable* all `Unique` above the granting item. This ensures U2 for read accesses.
|
||||
@ -363,7 +370,7 @@ impl<'tcx> Stack {
|
||||
let item = &mut self.borrows[idx];
|
||||
if item.perm == Permission::Unique {
|
||||
trace!("access: disabling item {:?}", item);
|
||||
Stack::check_protector(item, Some(tag), global)?;
|
||||
Stack::check_protector(item, Some((tag, access)), global)?;
|
||||
item.perm = Permission::Disabled;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user