use rustc_span::{source_map::DUMMY_SP, Span, SpanData, Symbol};
use crate::helpers::HexRange;
-use crate::stacked_borrows::{diagnostics::TagHistory, AccessKind, SbTag};
+use crate::stacked_borrows::{diagnostics::TagHistory, AccessKind};
use crate::*;
/// Details of premature program termination.
help: Option<String>,
history: Option<TagHistory>,
},
+ Int2PtrWithStrictProvenance,
Deadlock,
MultipleSymbolDefinitions {
link_name: Symbol,
Exit(code) => write!(f, "the evaluated program completed with exit code {}", code),
Abort(msg) => write!(f, "{}", msg),
UnsupportedInIsolation(msg) => write!(f, "{}", msg),
+ Int2PtrWithStrictProvenance =>
+ write!(
+ f,
+ "integer-to-pointer casts and `ptr::from_exposed_addr` are not supported with `-Zmiri-strict-provenance`"
+ ),
StackedBorrowsUb { msg, .. } => write!(f, "{}", msg),
Deadlock => write!(f, "the evaluated program deadlocked"),
MultipleSymbolDefinitions { link_name, .. } =>
/// Miri specific diagnostics
pub enum NonHaltingDiagnostic {
CreatedPointerTag(NonZeroU64),
- /// 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)>),
+ /// This `Item` was popped from the borrow stack, either due to an access with the given tag or
+ /// a deallocation when the second argument is `None`.
+ PoppedPointerTag(Item, Option<(SbTagExtra, AccessKind)>),
CreatedCallId(CallId),
CreatedAlloc(AllocId),
FreedAlloc(AllocId),
RejectedIsolatedOp(String),
+ ProgressReport,
+ Int2Ptr {
+ details: bool,
+ },
}
/// Level of Miri specific diagnostics
let title = match info {
Exit(code) => return Some(*code),
Abort(_) => Some("abnormal termination"),
- UnsupportedInIsolation(_) => Some("unsupported operation"),
+ UnsupportedInIsolation(_) | Int2PtrWithStrictProvenance =>
+ Some("unsupported operation"),
StackedBorrowsUb { .. } => Some("Undefined Behavior"),
Deadlock => Some("deadlock"),
MultipleSymbolDefinitions { .. } | SymbolShimClashing { .. } => None,
}
if let Some((protecting_tag, protecting_tag_span, protection_span)) = protected {
helps.push((Some(*protecting_tag_span), format!("{:?} was protected due to {:?} which was created here", tag, protecting_tag)));
- helps.push((Some(*protection_span), "this protector is live for this call".to_string()));
- }
- }
- Some(TagHistory::Untagged{ recently_created, recently_invalidated, matching_created, protected }) => {
- if let Some((range, span)) = recently_created {
- let msg = format!("tag was most recently created at offsets {}", HexRange(*range));
- helps.push((Some(*span), msg));
- }
- if let Some((range, span)) = recently_invalidated {
- let msg = format!("tag was later invalidated at offsets {}", HexRange(*range));
- helps.push((Some(*span), msg));
- }
- if let Some((range, span)) = matching_created {
- let msg = format!("this tag was also created here at offsets {}", HexRange(*range));
- helps.push((Some(*span), msg));
- }
- if let Some((protecting_tag, protecting_tag_span, protection_span)) = protected {
- helps.push((Some(*protecting_tag_span), format!("{:?} was protected due to a tag which was created here", protecting_tag)));
- helps.push((Some(*protection_span), "this protector is live for this call".to_string()));
+ helps.push((Some(*protection_span), format!("this protector is live for this call")));
}
}
None => {}
],
SymbolShimClashing { link_name, span } =>
vec![(Some(*span), format!("the `{}` symbol is defined here", link_name))],
+ Int2PtrWithStrictProvenance =>
+ vec![(None, format!("use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead"))],
_ => vec![],
};
(title, helps)
FreedAlloc(AllocId(id)) => format!("freed allocation with id {id}"),
RejectedIsolatedOp(ref op) =>
format!("{op} was made to return an error due to isolation"),
+ ProgressReport =>
+ format!("progress report: current operation being executed is here"),
+ Int2Ptr { .. } => format!("integer-to-pointer cast"),
};
let (title, diag_level) = match e {
RejectedIsolatedOp(_) =>
("operation rejected by isolation", DiagLevel::Warning),
- _ => ("tracking was triggered", DiagLevel::Note),
+ Int2Ptr { .. } => ("integer-to-pointer cast", DiagLevel::Warning),
+ CreatedPointerTag(..)
+ | PoppedPointerTag(..)
+ | CreatedCallId(..)
+ | CreatedAlloc(..)
+ | FreedAlloc(..)
+ | ProgressReport => ("tracking was triggered", DiagLevel::Note),
+ };
+
+ let helps = match e {
+ Int2Ptr { details: true } =>
+ vec![
+ (None, format!("This program is using integer-to-pointer casts or (equivalently) `ptr::from_exposed_addr`,")),
+ (None, format!("which means that Miri might miss pointer bugs in this program.")),
+ (None, format!("See https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation.")),
+ (None, format!("To ensure that Miri does not miss bugs in your program, use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead.")),
+ (None, format!("You can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics.")),
+ (None, format!("Alternatively, the `-Zmiri-permissive-provenance` flag disables this warning.")),
+ ],
+ _ => vec![],
};
- report_msg(this, diag_level, title, vec![msg], vec![], &stacktrace);
+ report_msg(this, diag_level, title, vec![msg], helps, &stacktrace);
}
});
}