use std::fmt;
use rustc_middle::mir::interpret::{alloc_range, AllocId, AllocRange};
-use rustc_span::{Span, SpanData};
+use rustc_span::{Span, SpanData, DUMMY_SP};
use rustc_target::abi::Size;
use crate::helpers::CurrentSpan;
#[derive(Clone, Debug)]
struct Protection {
+ /// The parent tag from which this protected tag was derived.
orig_tag: ProvenanceExtra,
tag: SbTag,
span: Span,
let protected = protector_tag
.and_then(|protector| {
- self.history.protectors.iter().find_map(|protection| {
- if protection.tag == protector {
- Some((protection.orig_tag, protection.span.data()))
- } else {
- None
- }
+ self.history.protectors.iter().find(|protection| {
+ protection.tag == protector
})
})
- .and_then(|(tag, call_span)| {
+ .and_then(|protection| {
self.history.creations.iter().rev().find_map(|event| {
- if ProvenanceExtra::Concrete(event.retag.new_tag) == tag {
- Some((event.retag.orig_tag, event.span.data(), call_span))
+ if ProvenanceExtra::Concrete(event.retag.new_tag) == protection.orig_tag {
+ Some((protection, event))
} else {
None
}
})
})
- .map(|(protecting_tag, protecting_tag_span, protection_span)| {
+ .map(|(protection, protection_parent)| {
+ let protected_tag = protection.tag;
[
(
format!(
- "{tag:?} was protected due to {protecting_tag:?} which was created here"
+ "{tag:?} cannot be used for memory access because that would remove protected tag {protected_tag:?}, protected by this function call",
),
- protecting_tag_span,
+ protection.span.data(),
),
- (format!("this protector is live for this call"), protection_span),
+ if protection_parent.retag.new_tag == tag {
+ (format!("{protected_tag:?} was derived from {tag:?}, the tag used for this memory access"), DUMMY_SP.data())
+ } else {
+ (
+ format!(
+ "{protected_tag:?} was derived from {protected_parent_tag:?}, which in turn was created here",
+ protected_parent_tag = protection_parent.retag.new_tag,
+ ),
+ protection_parent.span.data()
+ )
+ }
]
});
|
LL | let xraw: *mut i32 = unsafe { mem::transmute(&mut x) };
| ^^^^^^
-help: <TAG> was protected due to <TAG> which was created here
- --> $DIR/aliasing_mut1.rs:LL:CC
- |
-LL | let xraw: *mut i32 = unsafe { mem::transmute(&mut x) };
- | ^^^^^^
-help: this protector is live for this call
+help: <TAG> cannot be used for memory access because that would remove protected tag <TAG>, protected by this function call
--> $DIR/aliasing_mut1.rs:LL:CC
|
LL | pub fn safe(_x: &mut i32, _y: &mut i32) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = help: <TAG> was derived from <TAG>, the tag used for this memory access
= note: backtrace:
= note: inside `safe` at $DIR/aliasing_mut1.rs:LL:CC
note: inside `main` at $DIR/aliasing_mut1.rs:LL:CC
|
LL | let xref = &mut x;
| ^^^^^^
-help: <TAG> was protected due to <TAG> which was created here
- --> $DIR/aliasing_mut2.rs:LL:CC
- |
-LL | safe_raw(xshr, xraw);
- | ^^^^
-help: this protector is live for this call
+help: <TAG> cannot be used for memory access because that would remove protected tag <TAG>, protected by this function call
--> $DIR/aliasing_mut2.rs:LL:CC
|
LL | pub fn safe(_x: &i32, _y: &mut i32) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: <TAG> was derived from <TAG>, which in turn was created here
+ --> $DIR/aliasing_mut2.rs:LL:CC
+ |
+LL | safe_raw(xshr, xraw);
+ | ^^^^
= note: backtrace:
= note: inside `safe` at $DIR/aliasing_mut2.rs:LL:CC
note: inside `main` at $DIR/aliasing_mut2.rs:LL:CC
|
LL | let xref = &mut x;
| ^^^^^^
-help: <TAG> was protected due to <TAG> which was created here
- --> $DIR/aliasing_mut4.rs:LL:CC
- |
-LL | safe_raw(xshr, xraw as *mut _);
- | ^^^^
-help: this protector is live for this call
+help: <TAG> cannot be used for memory access because that would remove protected tag <TAG>, protected by this function call
--> $DIR/aliasing_mut4.rs:LL:CC
|
LL | pub fn safe(_x: &i32, _y: &mut Cell<i32>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: <TAG> was derived from <TAG>, which in turn was created here
+ --> $DIR/aliasing_mut4.rs:LL:CC
+ |
+LL | safe_raw(xshr, xraw as *mut _);
+ | ^^^^
= note: backtrace:
= note: inside `safe` at $DIR/aliasing_mut4.rs:LL:CC
note: inside `main` at $DIR/aliasing_mut4.rs:LL:CC
+++ /dev/null
-//@error-pattern: /deallocating while item \[Unique for .*\] is protected/
-
-fn inner(x: &mut i32, f: fn(&mut i32)) {
- // `f` may mutate, but it may not deallocate!
- f(x)
-}
-
-fn main() {
- inner(Box::leak(Box::new(0)), |x| {
- let raw = x as *mut _;
- drop(unsafe { Box::from_raw(raw) });
- });
-}
+++ /dev/null
-error: Undefined Behavior: deallocating while item [Unique for <TAG>] is protected by call ID
- --> RUSTLIB/alloc/src/alloc.rs:LL:CC
- |
-LL | unsafe { __rust_dealloc(ptr, layout.size(), layout.align()) }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocating while item [Unique for <TAG>] is protected by call ID
- |
- = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
- = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
- = note: backtrace:
- = note: inside `std::alloc::dealloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC
- = note: inside `<std::alloc::Global as std::alloc::Allocator>::deallocate` at RUSTLIB/alloc/src/alloc.rs:LL:CC
- = note: inside `alloc::alloc::box_free::<i32, std::alloc::Global>` at RUSTLIB/alloc/src/alloc.rs:LL:CC
- = note: inside `std::ptr::drop_in_place::<std::boxed::Box<i32>> - shim(Some(std::boxed::Box<i32>))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC
- = note: inside `std::mem::drop::<std::boxed::Box<i32>>` at RUSTLIB/core/src/mem/mod.rs:LL:CC
-note: inside closure at $DIR/deallocate_against_barrier1.rs:LL:CC
- --> $DIR/deallocate_against_barrier1.rs:LL:CC
- |
-LL | drop(unsafe { Box::from_raw(raw) });
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- = note: inside `<[closure@$DIR/deallocate_against_barrier1.rs:LL:CC] as std::ops::FnOnce<(&mut i32,)>>::call_once - shim` at RUSTLIB/core/src/ops/function.rs:LL:CC
-note: inside `inner` at $DIR/deallocate_against_barrier1.rs:LL:CC
- --> $DIR/deallocate_against_barrier1.rs:LL:CC
- |
-LL | f(x)
- | ^^^^
-note: inside `main` at $DIR/deallocate_against_barrier1.rs:LL:CC
- --> $DIR/deallocate_against_barrier1.rs:LL:CC
- |
-LL | / inner(Box::leak(Box::new(0)), |x| {
-LL | | let raw = x as *mut _;
-LL | | drop(unsafe { Box::from_raw(raw) });
-LL | | });
- | |______^
-
-note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
-
-error: aborting due to previous error
-
+++ /dev/null
-//@error-pattern: /deallocating while item \[SharedReadWrite for .*\] is protected/
-use std::marker::PhantomPinned;
-
-pub struct NotUnpin(i32, PhantomPinned);
-
-fn inner(x: &mut NotUnpin, f: fn(&mut NotUnpin)) {
- // `f` may mutate, but it may not deallocate!
- f(x)
-}
-
-fn main() {
- inner(Box::leak(Box::new(NotUnpin(0, PhantomPinned))), |x| {
- let raw = x as *mut _;
- drop(unsafe { Box::from_raw(raw) });
- });
-}
+++ /dev/null
-error: Undefined Behavior: deallocating while item [SharedReadWrite for <TAG>] is protected by call ID
- --> RUSTLIB/alloc/src/alloc.rs:LL:CC
- |
-LL | unsafe { __rust_dealloc(ptr, layout.size(), layout.align()) }
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocating while item [SharedReadWrite for <TAG>] is protected by call ID
- |
- = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
- = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
- = note: backtrace:
- = note: inside `std::alloc::dealloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC
- = note: inside `<std::alloc::Global as std::alloc::Allocator>::deallocate` at RUSTLIB/alloc/src/alloc.rs:LL:CC
- = note: inside `alloc::alloc::box_free::<NotUnpin, std::alloc::Global>` at RUSTLIB/alloc/src/alloc.rs:LL:CC
- = note: inside `std::ptr::drop_in_place::<std::boxed::Box<NotUnpin>> - shim(Some(std::boxed::Box<NotUnpin>))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC
- = note: inside `std::mem::drop::<std::boxed::Box<NotUnpin>>` at RUSTLIB/core/src/mem/mod.rs:LL:CC
-note: inside closure at $DIR/deallocate_against_barrier2.rs:LL:CC
- --> $DIR/deallocate_against_barrier2.rs:LL:CC
- |
-LL | drop(unsafe { Box::from_raw(raw) });
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- = note: inside `<[closure@$DIR/deallocate_against_barrier2.rs:LL:CC] as std::ops::FnOnce<(&mut NotUnpin,)>>::call_once - shim` at RUSTLIB/core/src/ops/function.rs:LL:CC
-note: inside `inner` at $DIR/deallocate_against_barrier2.rs:LL:CC
- --> $DIR/deallocate_against_barrier2.rs:LL:CC
- |
-LL | f(x)
- | ^^^^
-note: inside `main` at $DIR/deallocate_against_barrier2.rs:LL:CC
- --> $DIR/deallocate_against_barrier2.rs:LL:CC
- |
-LL | / inner(Box::leak(Box::new(NotUnpin(0, PhantomPinned))), |x| {
-LL | | let raw = x as *mut _;
-LL | | drop(unsafe { Box::from_raw(raw) });
-LL | | });
- | |______^
-
-note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
-
-error: aborting due to previous error
-
--- /dev/null
+//@error-pattern: /deallocating while item \[Unique for .*\] is protected/
+
+fn inner(x: &mut i32, f: fn(&mut i32)) {
+ // `f` may mutate, but it may not deallocate!
+ f(x)
+}
+
+fn main() {
+ inner(Box::leak(Box::new(0)), |x| {
+ let raw = x as *mut _;
+ drop(unsafe { Box::from_raw(raw) });
+ });
+}
--- /dev/null
+error: Undefined Behavior: deallocating while item [Unique for <TAG>] is protected by call ID
+ --> RUSTLIB/alloc/src/alloc.rs:LL:CC
+ |
+LL | unsafe { __rust_dealloc(ptr, layout.size(), layout.align()) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocating while item [Unique for <TAG>] is protected by call ID
+ |
+ = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
+ = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
+ = note: backtrace:
+ = note: inside `std::alloc::dealloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC
+ = note: inside `<std::alloc::Global as std::alloc::Allocator>::deallocate` at RUSTLIB/alloc/src/alloc.rs:LL:CC
+ = note: inside `alloc::alloc::box_free::<i32, std::alloc::Global>` at RUSTLIB/alloc/src/alloc.rs:LL:CC
+ = note: inside `std::ptr::drop_in_place::<std::boxed::Box<i32>> - shim(Some(std::boxed::Box<i32>))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC
+ = note: inside `std::mem::drop::<std::boxed::Box<i32>>` at RUSTLIB/core/src/mem/mod.rs:LL:CC
+note: inside closure at $DIR/deallocate_against_protector1.rs:LL:CC
+ --> $DIR/deallocate_against_protector1.rs:LL:CC
+ |
+LL | drop(unsafe { Box::from_raw(raw) });
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: inside `<[closure@$DIR/deallocate_against_protector1.rs:LL:CC] as std::ops::FnOnce<(&mut i32,)>>::call_once - shim` at RUSTLIB/core/src/ops/function.rs:LL:CC
+note: inside `inner` at $DIR/deallocate_against_protector1.rs:LL:CC
+ --> $DIR/deallocate_against_protector1.rs:LL:CC
+ |
+LL | f(x)
+ | ^^^^
+note: inside `main` at $DIR/deallocate_against_protector1.rs:LL:CC
+ --> $DIR/deallocate_against_protector1.rs:LL:CC
+ |
+LL | / inner(Box::leak(Box::new(0)), |x| {
+LL | | let raw = x as *mut _;
+LL | | drop(unsafe { Box::from_raw(raw) });
+LL | | });
+ | |______^
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to previous error
+
--- /dev/null
+//@error-pattern: /deallocating while item \[SharedReadWrite for .*\] is protected/
+use std::marker::PhantomPinned;
+
+pub struct NotUnpin(i32, PhantomPinned);
+
+fn inner(x: &mut NotUnpin, f: fn(&mut NotUnpin)) {
+ // `f` may mutate, but it may not deallocate!
+ f(x)
+}
+
+fn main() {
+ inner(Box::leak(Box::new(NotUnpin(0, PhantomPinned))), |x| {
+ let raw = x as *mut _;
+ drop(unsafe { Box::from_raw(raw) });
+ });
+}
--- /dev/null
+error: Undefined Behavior: deallocating while item [SharedReadWrite for <TAG>] is protected by call ID
+ --> RUSTLIB/alloc/src/alloc.rs:LL:CC
+ |
+LL | unsafe { __rust_dealloc(ptr, layout.size(), layout.align()) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocating while item [SharedReadWrite for <TAG>] is protected by call ID
+ |
+ = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
+ = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
+ = note: backtrace:
+ = note: inside `std::alloc::dealloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC
+ = note: inside `<std::alloc::Global as std::alloc::Allocator>::deallocate` at RUSTLIB/alloc/src/alloc.rs:LL:CC
+ = note: inside `alloc::alloc::box_free::<NotUnpin, std::alloc::Global>` at RUSTLIB/alloc/src/alloc.rs:LL:CC
+ = note: inside `std::ptr::drop_in_place::<std::boxed::Box<NotUnpin>> - shim(Some(std::boxed::Box<NotUnpin>))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC
+ = note: inside `std::mem::drop::<std::boxed::Box<NotUnpin>>` at RUSTLIB/core/src/mem/mod.rs:LL:CC
+note: inside closure at $DIR/deallocate_against_protector2.rs:LL:CC
+ --> $DIR/deallocate_against_protector2.rs:LL:CC
+ |
+LL | drop(unsafe { Box::from_raw(raw) });
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: inside `<[closure@$DIR/deallocate_against_protector2.rs:LL:CC] as std::ops::FnOnce<(&mut NotUnpin,)>>::call_once - shim` at RUSTLIB/core/src/ops/function.rs:LL:CC
+note: inside `inner` at $DIR/deallocate_against_protector2.rs:LL:CC
+ --> $DIR/deallocate_against_protector2.rs:LL:CC
+ |
+LL | f(x)
+ | ^^^^
+note: inside `main` at $DIR/deallocate_against_protector2.rs:LL:CC
+ --> $DIR/deallocate_against_protector2.rs:LL:CC
+ |
+LL | / inner(Box::leak(Box::new(NotUnpin(0, PhantomPinned))), |x| {
+LL | | let raw = x as *mut _;
+LL | | drop(unsafe { Box::from_raw(raw) });
+LL | | });
+ | |______^
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to previous error
+
|
LL | let p = x as *mut u32;
| ^
-help: <TAG> was protected due to <TAG> which was created here
- --> $DIR/illegal_write6.rs:LL:CC
- |
-LL | foo(x, p);
- | ^
-help: this protector is live for this call
+help: <TAG> cannot be used for memory access because that would remove protected tag <TAG>, protected by this function call
--> $DIR/illegal_write6.rs:LL:CC
|
LL | / fn foo(a: &mut u32, y: *mut u32) -> u32 {
LL | | return *a;
LL | | }
| |_^
+help: <TAG> was derived from <TAG>, which in turn was created here
+ --> $DIR/illegal_write6.rs:LL:CC
+ |
+LL | foo(x, p);
+ | ^
= note: backtrace:
= note: inside `foo` at $DIR/illegal_write6.rs:LL:CC
note: inside `main` at $DIR/illegal_write6.rs:LL:CC
+++ /dev/null
-fn inner(x: *mut i32, _y: &mut i32) {
- // If `x` and `y` alias, retagging is fine with this... but we really
- // shouldn't be allowed to use `x` at all because `y` was assumed to be
- // unique for the duration of this call.
- let _val = unsafe { *x }; //~ ERROR: protect
-}
-
-fn main() {
- let mut x = 0;
- let xraw = &mut x as *mut _;
- let xref = unsafe { &mut *xraw };
- inner(xraw, xref);
-}
+++ /dev/null
-error: Undefined Behavior: not granting access to tag <TAG> because incompatible item [Unique for <TAG>] is protected by call ID
- --> $DIR/invalidate_against_barrier1.rs:LL:CC
- |
-LL | let _val = unsafe { *x };
- | ^^ not granting access to tag <TAG> because incompatible item [Unique for <TAG>] is protected by call ID
- |
- = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
- = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
-help: <TAG> was created by a SharedReadWrite retag at offsets [0x0..0x4]
- --> $DIR/invalidate_against_barrier1.rs:LL:CC
- |
-LL | let xraw = &mut x as *mut _;
- | ^^^^^^
-help: <TAG> was protected due to <TAG> which was created here
- --> $DIR/invalidate_against_barrier1.rs:LL:CC
- |
-LL | inner(xraw, xref);
- | ^^^^
-help: this protector is live for this call
- --> $DIR/invalidate_against_barrier1.rs:LL:CC
- |
-LL | / fn inner(x: *mut i32, _y: &mut i32) {
-LL | | // If `x` and `y` alias, retagging is fine with this... but we really
-LL | | // shouldn't be allowed to use `x` at all because `y` was assumed to be
-LL | | // unique for the duration of this call.
-LL | | let _val = unsafe { *x };
-LL | | }
- | |_^
- = note: backtrace:
- = note: inside `inner` at $DIR/invalidate_against_barrier1.rs:LL:CC
-note: inside `main` at $DIR/invalidate_against_barrier1.rs:LL:CC
- --> $DIR/invalidate_against_barrier1.rs:LL:CC
- |
-LL | inner(xraw, xref);
- | ^^^^^^^^^^^^^^^^^
-
-note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
-
-error: aborting due to previous error
-
+++ /dev/null
-fn inner(x: *mut i32, _y: &i32) {
- // If `x` and `y` alias, retagging is fine with this... but we really
- // shouldn't be allowed to write to `x` at all because `y` was assumed to be
- // immutable for the duration of this call.
- unsafe { *x = 0 }; //~ ERROR: protect
-}
-
-fn main() {
- let mut x = 0;
- let xraw = &mut x as *mut _;
- let xref = unsafe { &*xraw };
- inner(xraw, xref);
-}
+++ /dev/null
-error: Undefined Behavior: not granting access to tag <TAG> because incompatible item [SharedReadOnly for <TAG>] is protected by call ID
- --> $DIR/invalidate_against_barrier2.rs:LL:CC
- |
-LL | unsafe { *x = 0 };
- | ^^^^^^ not granting access to tag <TAG> because incompatible item [SharedReadOnly for <TAG>] is protected by call ID
- |
- = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
- = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
-help: <TAG> was created by a SharedReadWrite retag at offsets [0x0..0x4]
- --> $DIR/invalidate_against_barrier2.rs:LL:CC
- |
-LL | let xraw = &mut x as *mut _;
- | ^^^^^^
-help: <TAG> was protected due to <TAG> which was created here
- --> $DIR/invalidate_against_barrier2.rs:LL:CC
- |
-LL | inner(xraw, xref);
- | ^^^^
-help: this protector is live for this call
- --> $DIR/invalidate_against_barrier2.rs:LL:CC
- |
-LL | / fn inner(x: *mut i32, _y: &i32) {
-LL | | // If `x` and `y` alias, retagging is fine with this... but we really
-LL | | // shouldn't be allowed to write to `x` at all because `y` was assumed to be
-LL | | // immutable for the duration of this call.
-LL | | unsafe { *x = 0 };
-LL | | }
- | |_^
- = note: backtrace:
- = note: inside `inner` at $DIR/invalidate_against_barrier2.rs:LL:CC
-note: inside `main` at $DIR/invalidate_against_barrier2.rs:LL:CC
- --> $DIR/invalidate_against_barrier2.rs:LL:CC
- |
-LL | inner(xraw, xref);
- | ^^^^^^^^^^^^^^^^^
-
-note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
-
-error: aborting due to previous error
-
--- /dev/null
+fn inner(x: *mut i32, _y: &mut i32) {
+ // If `x` and `y` alias, retagging is fine with this... but we really
+ // shouldn't be allowed to use `x` at all because `y` was assumed to be
+ // unique for the duration of this call.
+ let _val = unsafe { *x }; //~ ERROR: protect
+}
+
+fn main() {
+ let mut x = 0;
+ let xraw = &mut x as *mut _;
+ let xref = unsafe { &mut *xraw };
+ inner(xraw, xref);
+}
--- /dev/null
+error: Undefined Behavior: not granting access to tag <TAG> because incompatible item [Unique for <TAG>] is protected by call ID
+ --> $DIR/invalidate_against_protector1.rs:LL:CC
+ |
+LL | let _val = unsafe { *x };
+ | ^^ not granting access to tag <TAG> because incompatible item [Unique for <TAG>] is protected by call ID
+ |
+ = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
+ = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
+help: <TAG> was created by a SharedReadWrite retag at offsets [0x0..0x4]
+ --> $DIR/invalidate_against_protector1.rs:LL:CC
+ |
+LL | let xraw = &mut x as *mut _;
+ | ^^^^^^
+help: <TAG> cannot be used for memory access because that would remove protected tag <TAG>, protected by this function call
+ --> $DIR/invalidate_against_protector1.rs:LL:CC
+ |
+LL | / fn inner(x: *mut i32, _y: &mut i32) {
+LL | | // If `x` and `y` alias, retagging is fine with this... but we really
+LL | | // shouldn't be allowed to use `x` at all because `y` was assumed to be
+LL | | // unique for the duration of this call.
+LL | | let _val = unsafe { *x };
+LL | | }
+ | |_^
+help: <TAG> was derived from <TAG>, which in turn was created here
+ --> $DIR/invalidate_against_protector1.rs:LL:CC
+ |
+LL | inner(xraw, xref);
+ | ^^^^
+ = note: backtrace:
+ = note: inside `inner` at $DIR/invalidate_against_protector1.rs:LL:CC
+note: inside `main` at $DIR/invalidate_against_protector1.rs:LL:CC
+ --> $DIR/invalidate_against_protector1.rs:LL:CC
+ |
+LL | inner(xraw, xref);
+ | ^^^^^^^^^^^^^^^^^
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to previous error
+
--- /dev/null
+fn inner(x: *mut i32, _y: &i32) {
+ // If `x` and `y` alias, retagging is fine with this... but we really
+ // shouldn't be allowed to write to `x` at all because `y` was assumed to be
+ // immutable for the duration of this call.
+ unsafe { *x = 0 }; //~ ERROR: protect
+}
+
+fn main() {
+ let mut x = 0;
+ let xraw = &mut x as *mut _;
+ let xref = unsafe { &*xraw };
+ inner(xraw, xref);
+}
--- /dev/null
+error: Undefined Behavior: not granting access to tag <TAG> because incompatible item [SharedReadOnly for <TAG>] is protected by call ID
+ --> $DIR/invalidate_against_protector2.rs:LL:CC
+ |
+LL | unsafe { *x = 0 };
+ | ^^^^^^ not granting access to tag <TAG> because incompatible item [SharedReadOnly for <TAG>] is protected by call ID
+ |
+ = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
+ = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
+help: <TAG> was created by a SharedReadWrite retag at offsets [0x0..0x4]
+ --> $DIR/invalidate_against_protector2.rs:LL:CC
+ |
+LL | let xraw = &mut x as *mut _;
+ | ^^^^^^
+help: <TAG> cannot be used for memory access because that would remove protected tag <TAG>, protected by this function call
+ --> $DIR/invalidate_against_protector2.rs:LL:CC
+ |
+LL | / fn inner(x: *mut i32, _y: &i32) {
+LL | | // If `x` and `y` alias, retagging is fine with this... but we really
+LL | | // shouldn't be allowed to write to `x` at all because `y` was assumed to be
+LL | | // immutable for the duration of this call.
+LL | | unsafe { *x = 0 };
+LL | | }
+ | |_^
+help: <TAG> was derived from <TAG>, which in turn was created here
+ --> $DIR/invalidate_against_protector2.rs:LL:CC
+ |
+LL | inner(xraw, xref);
+ | ^^^^
+ = note: backtrace:
+ = note: inside `inner` at $DIR/invalidate_against_protector2.rs:LL:CC
+note: inside `main` at $DIR/invalidate_against_protector2.rs:LL:CC
+ --> $DIR/invalidate_against_protector2.rs:LL:CC
+ |
+LL | inner(xraw, xref);
+ | ^^^^^^^^^^^^^^^^^
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to previous error
+
|
LL | let ptr = Box::into_raw(Box::new(0i32));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-help: <TAG> was protected due to <TAG> which was created here
- --> $DIR/newtype_retagging.rs:LL:CC
- |
-LL | Newtype(&mut *ptr),
- | ^^^^^^^^^^^^^^^^^^
-help: this protector is live for this call
+help: <TAG> cannot be used for memory access because that would remove protected tag <TAG>, protected by this function call
--> $DIR/newtype_retagging.rs:LL:CC
|
LL | / fn dealloc_while_running(_n: Newtype<'_>, dealloc: impl FnOnce()) {
LL | | dealloc();
LL | | }
| |_^
+help: <TAG> was derived from <TAG>, which in turn was created here
+ --> $DIR/newtype_retagging.rs:LL:CC
+ |
+LL | Newtype(&mut *ptr),
+ | ^^^^^^^^^^^^^^^^^^
= note: backtrace:
= note: inside `std::boxed::Box::<i32>::from_raw_in` at RUSTLIB/alloc/src/boxed.rs:LL:CC
= note: inside `std::boxed::Box::<i32>::from_raw` at RUSTLIB/alloc/src/boxed.rs:LL:CC