Skip to content

Commit

Permalink
Make the non-halting diagnostic scheme independent of InterpError
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Jan 8, 2020
1 parent c0a7fd5 commit 90a8f2f
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 17 deletions.
34 changes: 26 additions & 8 deletions src/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
use rustc_mir::interpret::InterpErrorInfo;
use std::cell::RefCell;

use crate::*;

pub enum NonHaltingDiagnostic {
PoppedTrackedPointerTag(Item),
}

pub fn report_err<'tcx, 'mir>(
ecx: &InterpCx<'mir, 'tcx, Evaluator<'tcx>>,
mut e: InterpErrorInfo<'tcx>,
Expand All @@ -12,8 +17,6 @@ pub fn report_err<'tcx, 'mir>(
let info = info.downcast_ref::<TerminationInfo>().expect("invalid MachineStop payload");
match info {
TerminationInfo::Exit(code) => return Some(*code),
TerminationInfo::PoppedTrackedPointerTag(item) =>
format!("popped tracked tag for item {:?}", item),
TerminationInfo::Abort => format!("the evaluated program aborted execution"),
}
}
Expand All @@ -25,11 +28,23 @@ pub fn report_err<'tcx, 'mir>(
_ => e.to_string(),
};
e.print_backtrace();
report_msg(ecx, msg, true)
}

pub fn report_msg<'tcx, 'mir>(
ecx: &InterpCx<'mir, 'tcx, Evaluator<'tcx>>,
msg: String,
error: bool,
) -> Option<i64> {
if let Some(frame) = ecx.stack().last() {
let span = frame.current_source_info().unwrap().span;

let msg = format!("Miri evaluation error: {}", msg);
let mut err = ecx.tcx.sess.struct_span_err(span, msg.as_str());
let mut err = if error {
let msg = format!("Miri evaluation error: {}", msg);
ecx.tcx.sess.struct_span_err(span, msg.as_str())
} else {
ecx.tcx.sess.diagnostic().span_note_diag(span, msg.as_str())
};
let frames = ecx.generate_stacktrace(None);
err.span_label(span, msg);
// We iterate with indices because we need to look at the next frame (the caller).
Expand Down Expand Up @@ -61,12 +76,11 @@ pub fn report_err<'tcx, 'mir>(
return None;
}

use std::cell::RefCell;
thread_local! {
static ECX: RefCell<Vec<InterpErrorInfo<'static>>> = RefCell::new(Vec::new());
static ECX: RefCell<Vec<NonHaltingDiagnostic>> = RefCell::new(Vec::new());
}

pub fn register_err(e: InterpErrorInfo<'static>) {
pub fn register_err(e: NonHaltingDiagnostic) {
ECX.with(|ecx| ecx.borrow_mut().push(e));
}

Expand All @@ -76,7 +90,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let this = self.eval_context_ref();
ECX.with(|ecx| {
for e in ecx.borrow_mut().drain(..) {
report_err(this, e);
let msg = match e {
NonHaltingDiagnostic::PoppedTrackedPointerTag(item) =>
format!("popped tracked tag for item {:?}", item),
};
report_msg(this, msg, false);
}
});
}
Expand Down
1 change: 0 additions & 1 deletion src/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ pub struct MiriConfig {
/// Details of premature program termination.
pub enum TerminationInfo {
Exit(i64),
PoppedTrackedPointerTag(Item),
Abort,
}

Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub use crate::shims::tls::{EvalContextExt as TlsEvalContextExt, TlsData};
pub use crate::shims::EvalContextExt as ShimsEvalContextExt;

pub use crate::diagnostics::{
register_err, report_err, EvalContextExt as DiagnosticsEvalContextExt,
register_err, report_err, EvalContextExt as DiagnosticsEvalContextExt, NonHaltingDiagnostic,
};
pub use crate::eval::{create_ecx, eval_main, MiriConfig, TerminationInfo};
pub use crate::helpers::EvalContextExt as HelpersEvalContextExt;
Expand Down
8 changes: 1 addition & 7 deletions src/stacked_borrows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use std::rc::Rc;
use rustc_hir::Mutability;
use rustc::mir::RetagKind;
use rustc::ty::{self, layout::Size};
use rustc_mir::interpret::InterpError;

use crate::*;

Expand Down Expand Up @@ -267,12 +266,7 @@ impl<'tcx> Stack {
fn check_protector(item: &Item, tag: Option<Tag>, global: &GlobalState) -> InterpResult<'tcx> {
if let Tag::Tagged(id) = item.tag {
if Some(id) == global.tracked_pointer_tag {
register_err(
InterpError::MachineStop(Box::new(TerminationInfo::PoppedTrackedPointerTag(
item.clone(),
)))
.into(),
);
register_err(NonHaltingDiagnostic::PoppedTrackedPointerTag(item.clone()));
}
}
if let Some(call) = item.protector {
Expand Down

0 comments on commit 90a8f2f

Please sign in to comment.