Skip to content

Commit f1ae48c

Browse files
committed
Auto merge of rust-lang#3701 - RalfJung:extern-type-reborrow, r=saethlin
show warning when Stacked Borrows skips a reborrow due to 'extern type' When this happens, we can't actually be sure to catch all bugs -- LLVM will still get a `noalias` but Miri can't do reborrowing. That's not good.
2 parents 12cb742 + c45f464 commit f1ae48c

File tree

7 files changed

+83
-27
lines changed

7 files changed

+83
-27
lines changed

src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ pub mod diagnostics;
55
mod item;
66
mod stack;
77

8+
use std::cell::RefCell;
89
use std::cmp;
910
use std::fmt::Write;
1011
use std::mem;
@@ -820,7 +821,19 @@ trait EvalContextPrivExt<'tcx, 'ecx>: crate::MiriInterpCxExt<'tcx> {
820821
// See https://github.com/rust-lang/unsafe-code-guidelines/issues/276.
821822
let size = match size {
822823
Some(size) => size,
823-
None => return Ok(place.clone()),
824+
None => {
825+
// The first time this happens, show a warning.
826+
thread_local! { static WARNING_SHOWN: RefCell<bool> = const { RefCell::new(false) }; }
827+
WARNING_SHOWN.with_borrow_mut(|shown| {
828+
if *shown {
829+
return;
830+
}
831+
// Not yet shown. Show it!
832+
*shown = true;
833+
this.emit_diagnostic(NonHaltingDiagnostic::ExternTypeReborrow);
834+
});
835+
return Ok(place.clone());
836+
}
824837
};
825838

826839
// Compute new borrow.

src/tools/miri/src/diagnostics.rs

+26-5
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ pub enum NonHaltingDiagnostic {
130130
WeakMemoryOutdatedLoad {
131131
ptr: Pointer,
132132
},
133+
ExternTypeReborrow,
133134
}
134135

135136
/// Level of Miri specific diagnostics
@@ -593,6 +594,8 @@ impl<'tcx> MiriMachine<'tcx> {
593594
RejectedIsolatedOp(_) =>
594595
("operation rejected by isolation".to_string(), DiagLevel::Warning),
595596
Int2Ptr { .. } => ("integer-to-pointer cast".to_string(), DiagLevel::Warning),
597+
ExternTypeReborrow =>
598+
("reborrow of reference to `extern type`".to_string(), DiagLevel::Warning),
596599
CreatedPointerTag(..)
597600
| PoppedPointerTag(..)
598601
| CreatedCallId(..)
@@ -630,6 +633,8 @@ impl<'tcx> MiriMachine<'tcx> {
630633
Int2Ptr { .. } => format!("integer-to-pointer cast"),
631634
WeakMemoryOutdatedLoad { ptr } =>
632635
format!("weak memory emulation: outdated value returned from load at {ptr}"),
636+
ExternTypeReborrow =>
637+
format!("reborrow of a reference to `extern type` is not properly supported"),
633638
};
634639

635640
let notes = match &e {
@@ -647,34 +652,50 @@ impl<'tcx> MiriMachine<'tcx> {
647652
(
648653
None,
649654
format!(
650-
"This program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, which means that Miri might miss pointer bugs in this program."
655+
"this program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, which means that Miri might miss pointer bugs in this program"
651656
),
652657
),
653658
(
654659
None,
655660
format!(
656-
"See https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation."
661+
"see https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation"
657662
),
658663
),
659664
(
660665
None,
661666
format!(
662-
"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."
667+
"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"
663668
),
664669
),
665670
(
666671
None,
667672
format!(
668-
"You can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics."
673+
"you can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics"
669674
),
670675
),
671676
(
672677
None,
673678
format!(
674-
"Alternatively, `MIRIFLAGS=-Zmiri-permissive-provenance` disables this warning."
679+
"alternatively, `MIRIFLAGS=-Zmiri-permissive-provenance` disables this warning"
675680
),
676681
),
677682
],
683+
ExternTypeReborrow => {
684+
vec![
685+
(
686+
None,
687+
format!(
688+
"`extern type` are not compatible with the Stacked Borrows aliasing model implemented by Miri; Miri may miss bugs in this code"
689+
),
690+
),
691+
(
692+
None,
693+
format!(
694+
"try running with `MIRIFLAGS=-Zmiri-tree-borrows` to use the more permissive but also even more experimental Tree Borrows aliasing checks instead"
695+
),
696+
),
697+
]
698+
}
678699
_ => vec![],
679700
};
680701

src/tools/miri/tests/fail/extern-type-field-offset.stderr

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
warning: reborrow of reference to `extern type`
2+
--> $DIR/extern-type-field-offset.rs:LL:CC
3+
|
4+
LL | let x: &Newtype = unsafe { &*(&buf as *const _ as *const Newtype) };
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reborrow of a reference to `extern type` is not properly supported
6+
|
7+
= help: `extern type` are not compatible with the Stacked Borrows aliasing model implemented by Miri; Miri may miss bugs in this code
8+
= help: try running with `MIRIFLAGS=-Zmiri-tree-borrows` to use the more permissive but also even more experimental Tree Borrows aliasing checks instead
9+
= note: BACKTRACE:
10+
= note: inside `main` at $DIR/extern-type-field-offset.rs:LL:CC
11+
112
error: unsupported operation: `extern type` field does not have a known offset
213
--> $DIR/extern-type-field-offset.rs:LL:CC
314
|
@@ -10,5 +21,5 @@ LL | let _field = &x.a;
1021

1122
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
1223

13-
error: aborting due to 1 previous error
24+
error: aborting due to 1 previous error; 1 warning emitted
1425

src/tools/miri/tests/fail/intrinsics/ptr_metadata_uninit_slice_len.stderr

+5-5
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ warning: integer-to-pointer cast
44
LL | (*p.as_mut_ptr().cast::<[*const i32; 2]>())[0] = 4 as *const i32;
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ integer-to-pointer cast
66
|
7-
= help: This program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, which means that Miri might miss pointer bugs in this program.
8-
= help: See https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation.
9-
= help: 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.
10-
= help: You can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics.
11-
= help: Alternatively, `MIRIFLAGS=-Zmiri-permissive-provenance` disables this warning.
7+
= help: this program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, which means that Miri might miss pointer bugs in this program
8+
= help: see https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation
9+
= help: 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
10+
= help: you can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics
11+
= help: alternatively, `MIRIFLAGS=-Zmiri-permissive-provenance` disables this warning
1212
= note: BACKTRACE:
1313
= note: inside `main` at $DIR/ptr_metadata_uninit_slice_len.rs:LL:CC
1414

src/tools/miri/tests/pass/box.stack.stderr

+5-5
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ warning: integer-to-pointer cast
44
LL | let r2 = ((r as usize) + 0) as *mut i32;
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ integer-to-pointer cast
66
|
7-
= help: This program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, which means that Miri might miss pointer bugs in this program.
8-
= help: See https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation.
9-
= help: 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.
10-
= help: You can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics.
11-
= help: Alternatively, `MIRIFLAGS=-Zmiri-permissive-provenance` disables this warning.
7+
= help: this program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, which means that Miri might miss pointer bugs in this program
8+
= help: see https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation
9+
= help: 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
10+
= help: you can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics
11+
= help: alternatively, `MIRIFLAGS=-Zmiri-permissive-provenance` disables this warning
1212
= note: BACKTRACE:
1313
= note: inside `into_raw` at $DIR/box.rs:LL:CC
1414
note: inside `main`

src/tools/miri/tests/pass/extern_types.stack.stderr

+16-5
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,22 @@ warning: integer-to-pointer cast
44
LL | let x: &Foo = unsafe { &*(16 as *const Foo) };
55
| ^^^^^^^^^^^^^^^^^^ integer-to-pointer cast
66
|
7-
= help: This program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, which means that Miri might miss pointer bugs in this program.
8-
= help: See https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation.
9-
= help: 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.
10-
= help: You can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics.
11-
= help: Alternatively, `MIRIFLAGS=-Zmiri-permissive-provenance` disables this warning.
7+
= help: this program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, which means that Miri might miss pointer bugs in this program
8+
= help: see https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation
9+
= help: 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
10+
= help: you can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics
11+
= help: alternatively, `MIRIFLAGS=-Zmiri-permissive-provenance` disables this warning
12+
= note: BACKTRACE:
13+
= note: inside `main` at $DIR/extern_types.rs:LL:CC
14+
15+
warning: reborrow of reference to `extern type`
16+
--> $DIR/extern_types.rs:LL:CC
17+
|
18+
LL | let x: &Foo = unsafe { &*(16 as *const Foo) };
19+
| ^^^^^^^^^^^^^^^^^^^^ reborrow of a reference to `extern type` is not properly supported
20+
|
21+
= help: `extern type` are not compatible with the Stacked Borrows aliasing model implemented by Miri; Miri may miss bugs in this code
22+
= help: try running with `MIRIFLAGS=-Zmiri-tree-borrows` to use the more permissive but also even more experimental Tree Borrows aliasing checks instead
1223
= note: BACKTRACE:
1324
= note: inside `main` at $DIR/extern_types.rs:LL:CC
1425

src/tools/miri/tests/pass/stacked-borrows/issue-miri-2389.stderr

+5-5
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ warning: integer-to-pointer cast
44
LL | let wildcard = &root0 as *const Cell<i32> as usize as *const Cell<i32>;
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ integer-to-pointer cast
66
|
7-
= help: This program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, which means that Miri might miss pointer bugs in this program.
8-
= help: See https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation.
9-
= help: 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.
10-
= help: You can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics.
11-
= help: Alternatively, `MIRIFLAGS=-Zmiri-permissive-provenance` disables this warning.
7+
= help: this program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, which means that Miri might miss pointer bugs in this program
8+
= help: see https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation
9+
= help: 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
10+
= help: you can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics
11+
= help: alternatively, `MIRIFLAGS=-Zmiri-permissive-provenance` disables this warning
1212
= note: BACKTRACE:
1313
= note: inside `main` at $DIR/issue-miri-2389.rs:LL:CC
1414

0 commit comments

Comments
 (0)