From c1eddbc7fefe34bb0213261cb4aa18f4bc11b1c5 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 27 Jun 2022 20:22:50 -0400 Subject: [PATCH] show int2ptr warning once for each span (but don't duplicate the long help) --- src/diagnostics.rs | 10 ++++++---- src/intptrcast.rs | 17 ++++++++++++----- src/lib.rs | 1 + tests/pass/box.stderr | 13 +++++++++++++ 4 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/diagnostics.rs b/src/diagnostics.rs index 1a030bedd92..83949a75dee 100644 --- a/src/diagnostics.rs +++ b/src/diagnostics.rs @@ -69,7 +69,9 @@ pub enum NonHaltingDiagnostic { FreedAlloc(AllocId), RejectedIsolatedOp(String), ProgressReport, - Int2Ptr, + Int2Ptr { + details: bool, + }, } /// Level of Miri specific diagnostics @@ -451,13 +453,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx 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"), + Int2Ptr { .. } => format!("integer-to-pointer cast"), }; let (title, diag_level) = match e { RejectedIsolatedOp(_) => ("operation rejected by isolation", DiagLevel::Warning), - Int2Ptr => ("integer-to-pointer cast", DiagLevel::Warning), + Int2Ptr { .. } => ("integer-to-pointer cast", DiagLevel::Warning), CreatedPointerTag(..) | PoppedPointerTag(..) | CreatedCallId(..) @@ -467,7 +469,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx }; let helps = match e { - Int2Ptr => + Int2Ptr { details: true } => vec![ (None, format!("this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`,")), (None, format!("which means that Miri might miss pointer bugs in this program")), diff --git a/src/intptrcast.rs b/src/intptrcast.rs index 5e6088303f8..a95b20868d2 100644 --- a/src/intptrcast.rs +++ b/src/intptrcast.rs @@ -5,6 +5,7 @@ use log::trace; use rand::Rng; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_span::Span; use rustc_target::abi::{HasDataLayout, Size}; use crate::*; @@ -140,12 +141,18 @@ impl<'mir, 'tcx> GlobalStateInner { match global_state.provenance_mode { ProvenanceMode::Default => { - // The first time this happens, print a warning. - use std::sync::atomic::{AtomicBool, Ordering}; - static FIRST_WARNING: AtomicBool = AtomicBool::new(true); - if FIRST_WARNING.swap(false, Ordering::Relaxed) { - register_diagnostic(NonHaltingDiagnostic::Int2Ptr); + // The first time this happens at a particular location, print a warning. + thread_local! { + // `Span` is non-`Send`, so we use a thread-local instead. + static PAST_WARNINGS: RefCell> = RefCell::default(); } + PAST_WARNINGS.with_borrow_mut(|past_warnings| { + let first = past_warnings.is_empty(); + if past_warnings.insert(ecx.cur_span()) { + // Newly inserted, so first time we see this span. + register_diagnostic(NonHaltingDiagnostic::Int2Ptr { details: first }); + } + }); } ProvenanceMode::Strict => { throw_unsup_format!( diff --git a/src/lib.rs b/src/lib.rs index 621af171f4a..e199fae31ee 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,6 +8,7 @@ #![feature(yeet_expr)] #![feature(is_some_with)] #![feature(nonzero_ops)] +#![feature(local_key_cell_methods)] #![warn(rust_2018_idioms)] #![allow( clippy::collapsible_else_if, diff --git a/tests/pass/box.stderr b/tests/pass/box.stderr index eeb49eec5c0..d821fcd9d15 100644 --- a/tests/pass/box.stderr +++ b/tests/pass/box.stderr @@ -18,3 +18,16 @@ note: inside `main` at $DIR/box.rs:LL:CC LL | into_raw(); | ^^^^^^^^^^ +warning: integer-to-pointer cast + --> $DIR/box.rs:LL:CC + | +LL | let r = ((u.as_ptr() as usize) + 0) as *mut i32; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ integer-to-pointer cast + | + = note: inside `into_unique` at $DIR/box.rs:LL:CC +note: inside `main` at $DIR/box.rs:LL:CC + --> $DIR/box.rs:LL:CC + | +LL | into_unique(); + | ^^^^^^^^^^^^^ +