Skip to content

Commit c1eddbc

Browse files
committed
show int2ptr warning once for each span (but don't duplicate the long help)
1 parent 67e89b5 commit c1eddbc

File tree

4 files changed

+32
-9
lines changed

4 files changed

+32
-9
lines changed

src/diagnostics.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ pub enum NonHaltingDiagnostic {
6969
FreedAlloc(AllocId),
7070
RejectedIsolatedOp(String),
7171
ProgressReport,
72-
Int2Ptr,
72+
Int2Ptr {
73+
details: bool,
74+
},
7375
}
7476

7577
/// Level of Miri specific diagnostics
@@ -451,13 +453,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
451453
format!("{op} was made to return an error due to isolation"),
452454
ProgressReport =>
453455
format!("progress report: current operation being executed is here"),
454-
Int2Ptr => format!("integer-to-pointer cast"),
456+
Int2Ptr { .. } => format!("integer-to-pointer cast"),
455457
};
456458

457459
let (title, diag_level) = match e {
458460
RejectedIsolatedOp(_) =>
459461
("operation rejected by isolation", DiagLevel::Warning),
460-
Int2Ptr => ("integer-to-pointer cast", DiagLevel::Warning),
462+
Int2Ptr { .. } => ("integer-to-pointer cast", DiagLevel::Warning),
461463
CreatedPointerTag(..)
462464
| PoppedPointerTag(..)
463465
| CreatedCallId(..)
@@ -467,7 +469,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
467469
};
468470

469471
let helps = match e {
470-
Int2Ptr =>
472+
Int2Ptr { details: true } =>
471473
vec![
472474
(None, format!("this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`,")),
473475
(None, format!("which means that Miri might miss pointer bugs in this program")),

src/intptrcast.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use log::trace;
55
use rand::Rng;
66

77
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
8+
use rustc_span::Span;
89
use rustc_target::abi::{HasDataLayout, Size};
910

1011
use crate::*;
@@ -140,12 +141,18 @@ impl<'mir, 'tcx> GlobalStateInner {
140141

141142
match global_state.provenance_mode {
142143
ProvenanceMode::Default => {
143-
// The first time this happens, print a warning.
144-
use std::sync::atomic::{AtomicBool, Ordering};
145-
static FIRST_WARNING: AtomicBool = AtomicBool::new(true);
146-
if FIRST_WARNING.swap(false, Ordering::Relaxed) {
147-
register_diagnostic(NonHaltingDiagnostic::Int2Ptr);
144+
// The first time this happens at a particular location, print a warning.
145+
thread_local! {
146+
// `Span` is non-`Send`, so we use a thread-local instead.
147+
static PAST_WARNINGS: RefCell<FxHashSet<Span>> = RefCell::default();
148148
}
149+
PAST_WARNINGS.with_borrow_mut(|past_warnings| {
150+
let first = past_warnings.is_empty();
151+
if past_warnings.insert(ecx.cur_span()) {
152+
// Newly inserted, so first time we see this span.
153+
register_diagnostic(NonHaltingDiagnostic::Int2Ptr { details: first });
154+
}
155+
});
149156
}
150157
ProvenanceMode::Strict => {
151158
throw_unsup_format!(

src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#![feature(yeet_expr)]
99
#![feature(is_some_with)]
1010
#![feature(nonzero_ops)]
11+
#![feature(local_key_cell_methods)]
1112
#![warn(rust_2018_idioms)]
1213
#![allow(
1314
clippy::collapsible_else_if,

tests/pass/box.stderr

+13
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,16 @@ note: inside `main` at $DIR/box.rs:LL:CC
1818
LL | into_raw();
1919
| ^^^^^^^^^^
2020

21+
warning: integer-to-pointer cast
22+
--> $DIR/box.rs:LL:CC
23+
|
24+
LL | let r = ((u.as_ptr() as usize) + 0) as *mut i32;
25+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ integer-to-pointer cast
26+
|
27+
= note: inside `into_unique` at $DIR/box.rs:LL:CC
28+
note: inside `main` at $DIR/box.rs:LL:CC
29+
--> $DIR/box.rs:LL:CC
30+
|
31+
LL | into_unique();
32+
| ^^^^^^^^^^^^^
33+

0 commit comments

Comments
 (0)