about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2023-08-01 17:03:19 +0200
committerRalf Jung <post@ralfj.de>2023-08-01 17:57:13 +0200
commit8496292ddaec7696fa924d86cdea9ee26c1539b7 (patch)
tree7a73f83d6a5b4c64aa1b815265ec93abe12ec1e2
parent7d5886504caacb3e9073d54aaf0b8ee8289ebc7f (diff)
downloadrust-8496292ddaec7696fa924d86cdea9ee26c1539b7.tar.gz
rust-8496292ddaec7696fa924d86cdea9ee26c1539b7.zip
properly track why we checked whether a pointer is in-bounds
also simplify the in-bounds checking in Miri's borrow trackers
-rw-r--r--compiler/rustc_const_eval/messages.ftl2
-rw-r--r--compiler/rustc_const_eval/src/errors.rs8
-rw-r--r--compiler/rustc_const_eval/src/interpret/memory.rs23
-rw-r--r--compiler/rustc_const_eval/src/interpret/step.rs3
-rw-r--r--compiler/rustc_middle/src/mir/interpret/error.rs4
-rw-r--r--src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs16
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs62
-rw-r--r--src/tools/miri/tests/fail/alloc/deallocate-twice.rs2
-rw-r--r--src/tools/miri/tests/fail/alloc/deallocate-twice.stderr4
-rw-r--r--src/tools/miri/tests/fail/alloc/reallocate-change-alloc.rs2
-rw-r--r--src/tools/miri/tests/fail/alloc/reallocate-change-alloc.stderr4
-rw-r--r--src/tools/miri/tests/fail/alloc/reallocate-dangling.rs2
-rw-r--r--src/tools/miri/tests/fail/alloc/reallocate-dangling.stderr4
-rw-r--r--src/tools/miri/tests/fail/concurrency/thread_local_static_dealloc.rs2
-rw-r--r--src/tools/miri/tests/fail/concurrency/thread_local_static_dealloc.stderr4
-rw-r--r--src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_addr_of.rs2
-rw-r--r--src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_addr_of.stderr4
-rw-r--r--src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref.rs2
-rw-r--r--src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref.stderr4
-rw-r--r--src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_offset.rs11
-rw-r--r--src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_offset.stderr15
-rw-r--r--src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_project_underscore.rs (renamed from src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.rs)2
-rw-r--r--src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_project_underscore.stderr (renamed from src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.stderr)8
-rw-r--r--src/tools/miri/tests/fail/dangling_pointers/dangling_zst_deref.rs2
-rw-r--r--src/tools/miri/tests/fail/dangling_pointers/dangling_zst_deref.stderr4
-rw-r--r--src/tools/miri/tests/fail/dangling_pointers/stack_temporary.rs2
-rw-r--r--src/tools/miri/tests/fail/dangling_pointers/stack_temporary.stderr4
-rw-r--r--src/tools/miri/tests/fail/data_race/dealloc_read_race2.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/dealloc_read_race2.stderr4
-rw-r--r--src/tools/miri/tests/fail/data_race/dealloc_write_race2.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/dealloc_write_race2.stderr4
-rw-r--r--src/tools/miri/tests/fail/environ-gets-deallocated.rs2
-rw-r--r--src/tools/miri/tests/fail/environ-gets-deallocated.stderr4
-rw-r--r--src/tools/miri/tests/fail/generator-pinned-moved.rs2
-rw-r--r--src/tools/miri/tests/fail/generator-pinned-moved.stderr4
-rw-r--r--src/tools/miri/tests/fail/rc_as_ptr.rs2
-rw-r--r--src/tools/miri/tests/fail/rc_as_ptr.stderr4
-rw-r--r--src/tools/miri/tests/fail/shims/mmap_use_after_munmap.rs2
-rw-r--r--src/tools/miri/tests/fail/shims/mmap_use_after_munmap.stderr4
-rw-r--r--src/tools/miri/tests/fail/zst2.rs2
-rw-r--r--src/tools/miri/tests/fail/zst2.stderr4
-rw-r--r--tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.stderr4
-rw-r--r--tests/ui/consts/const-eval/heap/dealloc_intrinsic_duplicate.stderr2
-rw-r--r--tests/ui/consts/const-eval/issue-49296.stderr2
44 files changed, 130 insertions, 122 deletions
diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl
index 671c2be1de9..2905874eec5 100644
--- a/compiler/rustc_const_eval/messages.ftl
+++ b/compiler/rustc_const_eval/messages.ftl
@@ -282,7 +282,7 @@ const_eval_pointer_out_of_bounds =
         *[many] bytes
     } starting at offset {$ptr_offset} is out-of-bounds
 const_eval_pointer_use_after_free =
-    pointer to {$allocation} was dereferenced after this allocation got freed
+    {$bad_pointer_message}: {$alloc_id} has been freed, so this pointer is dangling
 const_eval_ptr_as_bytes_1 =
     this code performed an operation that depends on the underlying bytes representing a pointer
 const_eval_ptr_as_bytes_2 =
diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs
index e1109e584b7..8cbc68d9061 100644
--- a/compiler/rustc_const_eval/src/errors.rs
+++ b/compiler/rustc_const_eval/src/errors.rs
@@ -492,7 +492,7 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
             InvalidMeta(InvalidMetaKind::SliceTooBig) => const_eval_invalid_meta_slice,
             InvalidMeta(InvalidMetaKind::TooBig) => const_eval_invalid_meta,
             UnterminatedCString(_) => const_eval_unterminated_c_string,
-            PointerUseAfterFree(_) => const_eval_pointer_use_after_free,
+            PointerUseAfterFree(_, _) => const_eval_pointer_use_after_free,
             PointerOutOfBounds { ptr_size: Size::ZERO, .. } => const_eval_zst_pointer_out_of_bounds,
             PointerOutOfBounds { .. } => const_eval_pointer_out_of_bounds,
             DanglingIntPointer(0, _) => const_eval_dangling_null_pointer,
@@ -545,8 +545,10 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
             UnterminatedCString(ptr) | InvalidFunctionPointer(ptr) | InvalidVTablePointer(ptr) => {
                 builder.set_arg("pointer", ptr);
             }
-            PointerUseAfterFree(allocation) => {
-                builder.set_arg("allocation", allocation);
+            PointerUseAfterFree(alloc_id, msg) => {
+                builder
+                    .set_arg("alloc_id", alloc_id)
+                    .set_arg("bad_pointer_message", bad_pointer_message(msg, handler));
             }
             PointerOutOfBounds { alloc_id, alloc_size, ptr_offset, ptr_size, msg } => {
                 builder
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs
index 02d022a2252..940a312d03b 100644
--- a/compiler/rustc_const_eval/src/interpret/memory.rs
+++ b/compiler/rustc_const_eval/src/interpret/memory.rs
@@ -317,7 +317,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                         kind = "static_mem"
                     )
                 }
-                None => err_ub!(PointerUseAfterFree(alloc_id)),
+                None => err_ub!(PointerUseAfterFree(alloc_id, CheckInAllocMsg::MemoryAccessTest)),
             }
             .into());
         };
@@ -380,7 +380,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             M::enforce_alignment(self),
             CheckInAllocMsg::MemoryAccessTest,
             |alloc_id, offset, prov| {
-                let (size, align) = self.get_live_alloc_size_and_align(alloc_id)?;
+                let (size, align) = self
+                    .get_live_alloc_size_and_align(alloc_id, CheckInAllocMsg::MemoryAccessTest)?;
                 Ok((size, align, (alloc_id, offset, prov)))
             },
         )
@@ -404,7 +405,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             CheckAlignment::Error,
             msg,
             |alloc_id, _, _| {
-                let (size, align) = self.get_live_alloc_size_and_align(alloc_id)?;
+                let (size, align) = self.get_live_alloc_size_and_align(alloc_id, msg)?;
                 Ok((size, align, ()))
             },
         )?;
@@ -414,7 +415,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     /// Low-level helper function to check if a ptr is in-bounds and potentially return a reference
     /// to the allocation it points to. Supports both shared and mutable references, as the actual
     /// checking is offloaded to a helper closure. `align` defines whether and which alignment check
-    /// is done. Returns `None` for size 0, and otherwise `Some` of what `alloc_size` returned.
+    /// is done.
+    ///
+    /// If this returns `None`, the size is 0; it can however return `Some` even for size 0.
     fn check_and_deref_ptr<T>(
         &self,
         ptr: Pointer<Option<M::Provenance>>,
@@ -515,7 +518,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             }
             Some(GlobalAlloc::Function(..)) => throw_ub!(DerefFunctionPointer(id)),
             Some(GlobalAlloc::VTable(..)) => throw_ub!(DerefVTablePointer(id)),
-            None => throw_ub!(PointerUseAfterFree(id)),
+            None => throw_ub!(PointerUseAfterFree(id, CheckInAllocMsg::MemoryAccessTest)),
             Some(GlobalAlloc::Static(def_id)) => {
                 assert!(self.tcx.is_static(def_id));
                 assert!(!self.tcx.is_thread_local_static(def_id));
@@ -761,11 +764,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         }
     }
 
-    /// Obtain the size and alignment of a live allocation.
-    pub fn get_live_alloc_size_and_align(&self, id: AllocId) -> InterpResult<'tcx, (Size, Align)> {
+    /// Obtain the size and alignment of a *live* allocation.
+    fn get_live_alloc_size_and_align(
+        &self,
+        id: AllocId,
+        msg: CheckInAllocMsg,
+    ) -> InterpResult<'tcx, (Size, Align)> {
         let (size, align, kind) = self.get_alloc_info(id);
         if matches!(kind, AllocKind::Dead) {
-            throw_ub!(PointerUseAfterFree(id))
+            throw_ub!(PointerUseAfterFree(id, msg))
         }
         Ok((size, align))
     }
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index 91341ddacd1..59285a339af 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -224,8 +224,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
 
             Len(place) => {
                 let src = self.eval_place(place)?;
-                let op = self.place_to_op(&src)?;
-                let len = op.len(self)?;
+                let len = src.len(self)?;
                 self.write_scalar(Scalar::from_target_usize(len, self), &dest)?;
             }
 
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs
index d44dfa2172a..eaa6c0ce2d6 100644
--- a/compiler/rustc_middle/src/mir/interpret/error.rs
+++ b/compiler/rustc_middle/src/mir/interpret/error.rs
@@ -282,8 +282,8 @@ pub enum UndefinedBehaviorInfo<'a> {
     InvalidMeta(InvalidMetaKind),
     /// Reading a C string that does not end within its allocation.
     UnterminatedCString(Pointer),
-    /// Dereferencing a dangling pointer after it got freed.
-    PointerUseAfterFree(AllocId),
+    /// Using a pointer after it got freed.
+    PointerUseAfterFree(AllocId, CheckInAllocMsg),
     /// Used a pointer outside the bounds it is valid for.
     /// (If `ptr_size > 0`, determines the size of the memory range that was expected to be in-bounds.)
     PointerOutOfBounds {
diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
index 8059fddb100..e929091b396 100644
--- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
@@ -18,7 +18,7 @@ use rustc_middle::ty::{
     layout::{HasParamEnv, LayoutOf},
     Ty,
 };
-use rustc_target::abi::{Abi, Size};
+use rustc_target::abi::{Abi, Align, Size};
 
 use crate::borrow_tracker::{
     stacked_borrows::diagnostics::{AllocHistory, DiagnosticCx, DiagnosticCxBuilder},
@@ -619,6 +619,8 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
         retag_info: RetagInfo, // diagnostics info about this retag
     ) -> InterpResult<'tcx, Option<AllocId>> {
         let this = self.eval_context_mut();
+        // Ensure we bail out if the pointer goes out-of-bounds (see miri#1050).
+        this.check_ptr_access_align(place.ptr, size, Align::ONE, CheckInAllocMsg::InboundsTest)?;
 
         // It is crucial that this gets called on all code paths, to ensure we track tag creation.
         let log_creation = |this: &MiriInterpCx<'mir, 'tcx>,
@@ -707,18 +709,6 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
         let (alloc_id, base_offset, orig_tag) = this.ptr_get_alloc_id(place.ptr)?;
         log_creation(this, Some((alloc_id, base_offset, orig_tag)))?;
 
-        // Ensure we bail out if the pointer goes out-of-bounds (see miri#1050).
-        let (alloc_size, _) = this.get_live_alloc_size_and_align(alloc_id)?;
-        if base_offset + size > alloc_size {
-            throw_ub!(PointerOutOfBounds {
-                alloc_id,
-                alloc_size,
-                ptr_offset: this.target_usize_to_isize(base_offset.bytes()),
-                ptr_size: size,
-                msg: CheckInAllocMsg::InboundsTest
-            });
-        }
-
         trace!(
             "reborrow: reference {:?} derived from {:?} (pointee {}): {:?}, size {}",
             new_tag,
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
index 9073f695442..b2dbe8a70f0 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
@@ -1,6 +1,6 @@
 use log::trace;
 
-use rustc_target::abi::{Abi, Size};
+use rustc_target::abi::{Abi, Align, Size};
 
 use crate::borrow_tracker::{AccessKind, GlobalStateInner, ProtectorKind, RetagFields};
 use rustc_middle::{
@@ -182,6 +182,8 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
         new_tag: BorTag,
     ) -> InterpResult<'tcx, Option<(AllocId, BorTag)>> {
         let this = self.eval_context_mut();
+        // Ensure we bail out if the pointer goes out-of-bounds (see miri#1050).
+        this.check_ptr_access_align(place.ptr, ptr_size, Align::ONE, CheckInAllocMsg::InboundsTest)?;
 
         // It is crucial that this gets called on all code paths, to ensure we track tag creation.
         let log_creation = |this: &MiriInterpCx<'mir, 'tcx>,
@@ -202,51 +204,33 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
         };
 
         trace!("Reborrow of size {:?}", ptr_size);
-        let (alloc_id, base_offset, parent_prov) = if ptr_size > Size::ZERO {
-            this.ptr_get_alloc_id(place.ptr)?
-        } else {
-            match this.ptr_try_get_alloc_id(place.ptr) {
-                Ok(data) => data,
-                Err(_) => {
-                    // This pointer doesn't come with an AllocId, so there's no
-                    // memory to do retagging in.
-                    trace!(
-                        "reborrow of size 0: reference {:?} derived from {:?} (pointee {})",
-                        new_tag,
-                        place.ptr,
-                        place.layout.ty,
-                    );
-                    log_creation(this, None)?;
-                    return Ok(None);
-                }
+        let (alloc_id, base_offset, parent_prov) = match this.ptr_try_get_alloc_id(place.ptr) {
+            Ok(data) => {
+                // Unlike SB, we *do* a proper retag for size 0 if can identify the allocation.
+                // After all, the pointer may be lazily initialized outside this initial range.
+                data
+            },
+            Err(_) => {
+                assert_eq!(ptr_size, Size::ZERO); // we did the deref check above, size has to be 0 here
+                // This pointer doesn't come with an AllocId, so there's no
+                // memory to do retagging in.
+                trace!(
+                    "reborrow of size 0: reference {:?} derived from {:?} (pointee {})",
+                    new_tag,
+                    place.ptr,
+                    place.layout.ty,
+                );
+                log_creation(this, None)?;
+                return Ok(None);
             }
         };
+        log_creation(this, Some((alloc_id, base_offset, parent_prov)))?;
+
         let orig_tag = match parent_prov {
             ProvenanceExtra::Wildcard => return Ok(None), // TODO: handle wildcard pointers
             ProvenanceExtra::Concrete(tag) => tag,
         };
 
-        // Protection against trying to get a reference to a vtable:
-        // vtables do not have an alloc_extra so the call to
-        // `get_alloc_extra` that follows fails.
-        let (alloc_size, _align, alloc_kind) = this.get_alloc_info(alloc_id);
-        if ptr_size == Size::ZERO && !matches!(alloc_kind, AllocKind::LiveData) {
-            return Ok(Some((alloc_id, orig_tag)));
-        }
-
-        log_creation(this, Some((alloc_id, base_offset, parent_prov)))?;
-
-        // Ensure we bail out if the pointer goes out-of-bounds (see miri#1050).
-        if base_offset + ptr_size > alloc_size {
-            throw_ub!(PointerOutOfBounds {
-                alloc_id,
-                alloc_size,
-                ptr_offset: this.target_usize_to_isize(base_offset.bytes()),
-                ptr_size,
-                msg: CheckInAllocMsg::InboundsTest
-            });
-        }
-
         trace!(
             "reborrow: reference {:?} derived from {:?} (pointee {}): {:?}, size {}",
             new_tag,
diff --git a/src/tools/miri/tests/fail/alloc/deallocate-twice.rs b/src/tools/miri/tests/fail/alloc/deallocate-twice.rs
index f07bbda4a9b..7a3ff84b2cb 100644
--- a/src/tools/miri/tests/fail/alloc/deallocate-twice.rs
+++ b/src/tools/miri/tests/fail/alloc/deallocate-twice.rs
@@ -1,6 +1,6 @@
 use std::alloc::{alloc, dealloc, Layout};
 
-//@error-in-other-file: dereferenced after this allocation got freed
+//@error-in-other-file: has been freed
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/alloc/deallocate-twice.stderr b/src/tools/miri/tests/fail/alloc/deallocate-twice.stderr
index fa7a74ee13c..23d145e7d30 100644
--- a/src/tools/miri/tests/fail/alloc/deallocate-twice.stderr
+++ b/src/tools/miri/tests/fail/alloc/deallocate-twice.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: pointer to ALLOC was dereferenced after this allocation got freed
+error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling
   --> RUSTLIB/alloc/src/alloc.rs:LL:CC
    |
 LL |     unsafe { __rust_dealloc(ptr, layout.size(), layout.align()) }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pointer to ALLOC was dereferenced after this allocation got freed
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
diff --git a/src/tools/miri/tests/fail/alloc/reallocate-change-alloc.rs b/src/tools/miri/tests/fail/alloc/reallocate-change-alloc.rs
index 3ad56da2c2f..ecdd3ae5fee 100644
--- a/src/tools/miri/tests/fail/alloc/reallocate-change-alloc.rs
+++ b/src/tools/miri/tests/fail/alloc/reallocate-change-alloc.rs
@@ -4,6 +4,6 @@ fn main() {
     unsafe {
         let x = alloc(Layout::from_size_align_unchecked(1, 1));
         let _y = realloc(x, Layout::from_size_align_unchecked(1, 1), 1);
-        let _z = *x; //~ ERROR: dereferenced after this allocation got freed
+        let _z = *x; //~ ERROR: has been freed
     }
 }
diff --git a/src/tools/miri/tests/fail/alloc/reallocate-change-alloc.stderr b/src/tools/miri/tests/fail/alloc/reallocate-change-alloc.stderr
index 5631dcb4cc0..7c7cec211b7 100644
--- a/src/tools/miri/tests/fail/alloc/reallocate-change-alloc.stderr
+++ b/src/tools/miri/tests/fail/alloc/reallocate-change-alloc.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: pointer to ALLOC was dereferenced after this allocation got freed
+error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
   --> $DIR/reallocate-change-alloc.rs:LL:CC
    |
 LL |         let _z = *x;
-   |                  ^^ pointer to ALLOC was dereferenced after this allocation got freed
+   |                  ^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
diff --git a/src/tools/miri/tests/fail/alloc/reallocate-dangling.rs b/src/tools/miri/tests/fail/alloc/reallocate-dangling.rs
index 130e2a8301e..622348ad190 100644
--- a/src/tools/miri/tests/fail/alloc/reallocate-dangling.rs
+++ b/src/tools/miri/tests/fail/alloc/reallocate-dangling.rs
@@ -1,6 +1,6 @@
 use std::alloc::{alloc, dealloc, realloc, Layout};
 
-//@error-in-other-file: dereferenced after this allocation got freed
+//@error-in-other-file: has been freed
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/alloc/reallocate-dangling.stderr b/src/tools/miri/tests/fail/alloc/reallocate-dangling.stderr
index b1460bfb763..9c222154716 100644
--- a/src/tools/miri/tests/fail/alloc/reallocate-dangling.stderr
+++ b/src/tools/miri/tests/fail/alloc/reallocate-dangling.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: pointer to ALLOC was dereferenced after this allocation got freed
+error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling
   --> RUSTLIB/alloc/src/alloc.rs:LL:CC
    |
 LL |     unsafe { __rust_realloc(ptr, layout.size(), layout.align(), new_size) }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pointer to ALLOC was dereferenced after this allocation got freed
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
diff --git a/src/tools/miri/tests/fail/concurrency/thread_local_static_dealloc.rs b/src/tools/miri/tests/fail/concurrency/thread_local_static_dealloc.rs
index d89c670b632..d5e6d37226a 100644
--- a/src/tools/miri/tests/fail/concurrency/thread_local_static_dealloc.rs
+++ b/src/tools/miri/tests/fail/concurrency/thread_local_static_dealloc.rs
@@ -11,6 +11,6 @@ unsafe impl Send for SendRaw {}
 fn main() {
     unsafe {
         let dangling_ptr = std::thread::spawn(|| SendRaw(&TLS as *const u8)).join().unwrap();
-        let _val = *dangling_ptr.0; //~ ERROR: dereferenced after this allocation got freed
+        let _val = *dangling_ptr.0; //~ ERROR: has been freed
     }
 }
diff --git a/src/tools/miri/tests/fail/concurrency/thread_local_static_dealloc.stderr b/src/tools/miri/tests/fail/concurrency/thread_local_static_dealloc.stderr
index cc3e5639878..0cb8aa29001 100644
--- a/src/tools/miri/tests/fail/concurrency/thread_local_static_dealloc.stderr
+++ b/src/tools/miri/tests/fail/concurrency/thread_local_static_dealloc.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: pointer to ALLOC was dereferenced after this allocation got freed
+error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
   --> $DIR/thread_local_static_dealloc.rs:LL:CC
    |
 LL |         let _val = *dangling_ptr.0;
-   |                    ^^^^^^^^^^^^^^^ pointer to ALLOC was dereferenced after this allocation got freed
+   |                    ^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_addr_of.rs b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_addr_of.rs
index 4249c1cbf01..49f3ae306a0 100644
--- a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_addr_of.rs
+++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_addr_of.rs
@@ -7,6 +7,6 @@ fn main() {
         let b = Box::new(42);
         &*b as *const i32
     };
-    let x = unsafe { ptr::addr_of!(*p) }; //~ ERROR: dereferenced after this allocation got freed
+    let x = unsafe { ptr::addr_of!(*p) }; //~ ERROR: has been freed
     panic!("this should never print: {:?}", x);
 }
diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_addr_of.stderr b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_addr_of.stderr
index 5f081afe68a..398f216e731 100644
--- a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_addr_of.stderr
+++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_addr_of.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: pointer to ALLOC was dereferenced after this allocation got freed
+error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
   --> $DIR/dangling_pointer_addr_of.rs:LL:CC
    |
 LL |     let x = unsafe { ptr::addr_of!(*p) };
-   |                      ^^^^^^^^^^^^^^^^^ pointer to ALLOC was dereferenced after this allocation got freed
+   |                      ^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref.rs b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref.rs
index ad2a599b60b..675e3e15da8 100644
--- a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref.rs
+++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref.rs
@@ -6,6 +6,6 @@ fn main() {
         let b = Box::new(42);
         &*b as *const i32
     };
-    let x = unsafe { *p }; //~ ERROR: dereferenced after this allocation got freed
+    let x = unsafe { *p }; //~ ERROR: has been freed
     panic!("this should never print: {}", x);
 }
diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref.stderr b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref.stderr
index cb323818845..cb95d71a605 100644
--- a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref.stderr
+++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: pointer to ALLOC was dereferenced after this allocation got freed
+error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
   --> $DIR/dangling_pointer_deref.rs:LL:CC
    |
 LL |     let x = unsafe { *p };
-   |                      ^^ pointer to ALLOC was dereferenced after this allocation got freed
+   |                      ^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_offset.rs b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_offset.rs
new file mode 100644
index 00000000000..65eca07a070
--- /dev/null
+++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_offset.rs
@@ -0,0 +1,11 @@
+// Make sure we find these even with many checks disabled.
+//@compile-flags: -Zmiri-disable-alignment-check -Zmiri-disable-stacked-borrows -Zmiri-disable-validation
+
+fn main() {
+    let p = {
+        let b = Box::new(42);
+        &*b as *const i32
+    };
+    let x = unsafe { p.offset(42) }; //~ ERROR: /out-of-bounds pointer arithmetic: .* has been freed/
+    panic!("this should never print: {:?}", x);
+}
diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_offset.stderr b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_offset.stderr
new file mode 100644
index 00000000000..85bd2bed9c3
--- /dev/null
+++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_offset.stderr
@@ -0,0 +1,15 @@
+error: Undefined Behavior: out-of-bounds pointer arithmetic: ALLOC has been freed, so this pointer is dangling
+  --> $DIR/dangling_pointer_offset.rs:LL:CC
+   |
+LL |     let x = unsafe { p.offset(42) };
+   |                      ^^^^^^^^^^^^ out-of-bounds pointer arithmetic: ALLOC has been freed, so this pointer is dangling
+   |
+   = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
+   = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
+   = note: BACKTRACE:
+   = note: inside `main` at $DIR/dangling_pointer_offset.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to previous error
+
diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.rs b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_project_underscore.rs
index 7c5f440b774..4c641243950 100644
--- a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.rs
+++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_project_underscore.rs
@@ -7,7 +7,7 @@ fn main() {
         &*b as *const i32
     };
     unsafe {
-        let _ = *p; //~ ERROR: dereferenced after this allocation got freed
+        let _ = *p; //~ ERROR: has been freed
     }
     panic!("this should never print");
 }
diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.stderr b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_project_underscore.stderr
index 7b76389c753..f2d58fe7697 100644
--- a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.stderr
+++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_project_underscore.stderr
@@ -1,13 +1,13 @@
-error: Undefined Behavior: pointer to ALLOC was dereferenced after this allocation got freed
-  --> $DIR/dangling_pointer_deref_underscore.rs:LL:CC
+error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
+  --> $DIR/dangling_pointer_project_underscore.rs:LL:CC
    |
 LL |         let _ = *p;
-   |                 ^^ pointer to ALLOC was dereferenced after this allocation got freed
+   |                 ^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
    = note: BACKTRACE:
-   = note: inside `main` at $DIR/dangling_pointer_deref_underscore.rs:LL:CC
+   = note: inside `main` at $DIR/dangling_pointer_project_underscore.rs:LL:CC
 
 note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
 
diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_zst_deref.rs b/src/tools/miri/tests/fail/dangling_pointers/dangling_zst_deref.rs
index e749eb896e2..a1fefe04ab6 100644
--- a/src/tools/miri/tests/fail/dangling_pointers/dangling_zst_deref.rs
+++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_zst_deref.rs
@@ -6,5 +6,5 @@ fn main() {
         let b = Box::new(42);
         &*b as *const i32 as *const ()
     };
-    let _x = unsafe { *p }; //~ ERROR: dereferenced after this allocation got freed
+    let _x = unsafe { *p }; //~ ERROR: has been freed
 }
diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_zst_deref.stderr b/src/tools/miri/tests/fail/dangling_pointers/dangling_zst_deref.stderr
index 02db6302a0a..c15f17f3b82 100644
--- a/src/tools/miri/tests/fail/dangling_pointers/dangling_zst_deref.stderr
+++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_zst_deref.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: pointer to ALLOC was dereferenced after this allocation got freed
+error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
   --> $DIR/dangling_zst_deref.rs:LL:CC
    |
 LL |     let _x = unsafe { *p };
-   |                       ^^ pointer to ALLOC was dereferenced after this allocation got freed
+   |                       ^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
diff --git a/src/tools/miri/tests/fail/dangling_pointers/stack_temporary.rs b/src/tools/miri/tests/fail/dangling_pointers/stack_temporary.rs
index c193d5fe0b3..5f8a1988b3c 100644
--- a/src/tools/miri/tests/fail/dangling_pointers/stack_temporary.rs
+++ b/src/tools/miri/tests/fail/dangling_pointers/stack_temporary.rs
@@ -8,7 +8,7 @@ unsafe fn make_ref<'a>(x: *mut i32) -> &'a mut i32 {
 fn main() {
     unsafe {
         let x = make_ref(&mut 0); // The temporary storing "0" is deallocated at the ";"!
-        let val = *x; //~ ERROR: dereferenced after this allocation got freed
+        let val = *x; //~ ERROR: has been freed
         println!("{}", val);
     }
 }
diff --git a/src/tools/miri/tests/fail/dangling_pointers/stack_temporary.stderr b/src/tools/miri/tests/fail/dangling_pointers/stack_temporary.stderr
index 679e4809ca6..500f28a3cbc 100644
--- a/src/tools/miri/tests/fail/dangling_pointers/stack_temporary.stderr
+++ b/src/tools/miri/tests/fail/dangling_pointers/stack_temporary.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: pointer to ALLOC was dereferenced after this allocation got freed
+error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
   --> $DIR/stack_temporary.rs:LL:CC
    |
 LL |         let val = *x;
-   |                   ^^ pointer to ALLOC was dereferenced after this allocation got freed
+   |                   ^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
diff --git a/src/tools/miri/tests/fail/data_race/dealloc_read_race2.rs b/src/tools/miri/tests/fail/data_race/dealloc_read_race2.rs
index 5d7a0cc1dc9..c921ce6b716 100644
--- a/src/tools/miri/tests/fail/data_race/dealloc_read_race2.rs
+++ b/src/tools/miri/tests/fail/data_race/dealloc_read_race2.rs
@@ -32,7 +32,7 @@ pub fn main() {
             let ptr = ptr; // avoid field capturing
             // Also an error of the form: Data race detected between (1) Deallocate on thread `<unnamed>` and (2) Read on thread `<unnamed>`
             // but the invalid allocation is detected first.
-            *ptr.0 //~ ERROR: dereferenced after this allocation got freed
+            *ptr.0 //~ ERROR: has been freed
         });
 
         j1.join().unwrap();
diff --git a/src/tools/miri/tests/fail/data_race/dealloc_read_race2.stderr b/src/tools/miri/tests/fail/data_race/dealloc_read_race2.stderr
index f303d57c8bd..4efc35c15e2 100644
--- a/src/tools/miri/tests/fail/data_race/dealloc_read_race2.stderr
+++ b/src/tools/miri/tests/fail/data_race/dealloc_read_race2.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: pointer to ALLOC was dereferenced after this allocation got freed
+error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
   --> $DIR/dealloc_read_race2.rs:LL:CC
    |
 LL |             *ptr.0
-   |             ^^^^^^ pointer to ALLOC was dereferenced after this allocation got freed
+   |             ^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
diff --git a/src/tools/miri/tests/fail/data_race/dealloc_write_race2.rs b/src/tools/miri/tests/fail/data_race/dealloc_write_race2.rs
index a7f43f03c02..e01132202d4 100644
--- a/src/tools/miri/tests/fail/data_race/dealloc_write_race2.rs
+++ b/src/tools/miri/tests/fail/data_race/dealloc_write_race2.rs
@@ -31,7 +31,7 @@ pub fn main() {
             let ptr = ptr; // avoid field capturing
             // Also an error of the form: Data race detected between (1) Deallocate on thread `<unnamed>` and (2) Write on thread `<unnamed>`
             // but the invalid allocation is detected first.
-            *ptr.0 = 2; //~ ERROR: dereferenced after this allocation got freed
+            *ptr.0 = 2; //~ ERROR: has been freed
         });
 
         j1.join().unwrap();
diff --git a/src/tools/miri/tests/fail/data_race/dealloc_write_race2.stderr b/src/tools/miri/tests/fail/data_race/dealloc_write_race2.stderr
index 23b8e9ade0e..fad525830e6 100644
--- a/src/tools/miri/tests/fail/data_race/dealloc_write_race2.stderr
+++ b/src/tools/miri/tests/fail/data_race/dealloc_write_race2.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: pointer to ALLOC was dereferenced after this allocation got freed
+error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
   --> $DIR/dealloc_write_race2.rs:LL:CC
    |
 LL |             *ptr.0 = 2;
-   |             ^^^^^^^^^^ pointer to ALLOC was dereferenced after this allocation got freed
+   |             ^^^^^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
diff --git a/src/tools/miri/tests/fail/environ-gets-deallocated.rs b/src/tools/miri/tests/fail/environ-gets-deallocated.rs
index e4597140b84..6dcf1fdb1c7 100644
--- a/src/tools/miri/tests/fail/environ-gets-deallocated.rs
+++ b/src/tools/miri/tests/fail/environ-gets-deallocated.rs
@@ -20,5 +20,5 @@ fn main() {
     let pointer = get_environ();
     let _x = unsafe { *pointer };
     std::env::set_var("FOO", "BAR");
-    let _y = unsafe { *pointer }; //~ ERROR: dereferenced after this allocation got freed
+    let _y = unsafe { *pointer }; //~ ERROR: has been freed
 }
diff --git a/src/tools/miri/tests/fail/environ-gets-deallocated.stderr b/src/tools/miri/tests/fail/environ-gets-deallocated.stderr
index a2d343bf865..6332846d5d8 100644
--- a/src/tools/miri/tests/fail/environ-gets-deallocated.stderr
+++ b/src/tools/miri/tests/fail/environ-gets-deallocated.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: pointer to ALLOC was dereferenced after this allocation got freed
+error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
   --> $DIR/environ-gets-deallocated.rs:LL:CC
    |
 LL |     let _y = unsafe { *pointer };
-   |                       ^^^^^^^^ pointer to ALLOC was dereferenced after this allocation got freed
+   |                       ^^^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
diff --git a/src/tools/miri/tests/fail/generator-pinned-moved.rs b/src/tools/miri/tests/fail/generator-pinned-moved.rs
index 29dc6e56f7c..33348ace9c4 100644
--- a/src/tools/miri/tests/fail/generator-pinned-moved.rs
+++ b/src/tools/miri/tests/fail/generator-pinned-moved.rs
@@ -13,7 +13,7 @@ fn firstn() -> impl Generator<Yield = u64, Return = ()> {
         *num += 0;
 
         yield *num;
-        *num += 1; //~ERROR: dereferenced after this allocation got freed
+        *num += 1; //~ERROR: has been freed
     }
 }
 
diff --git a/src/tools/miri/tests/fail/generator-pinned-moved.stderr b/src/tools/miri/tests/fail/generator-pinned-moved.stderr
index 80c5794736a..3eb17f05584 100644
--- a/src/tools/miri/tests/fail/generator-pinned-moved.stderr
+++ b/src/tools/miri/tests/fail/generator-pinned-moved.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: pointer to ALLOC was dereferenced after this allocation got freed
+error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
   --> $DIR/generator-pinned-moved.rs:LL:CC
    |
 LL |         *num += 1;
-   |         ^^^^^^^^^ pointer to ALLOC was dereferenced after this allocation got freed
+   |         ^^^^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
diff --git a/src/tools/miri/tests/fail/rc_as_ptr.rs b/src/tools/miri/tests/fail/rc_as_ptr.rs
index 6aea1870748..ebcf49b8f99 100644
--- a/src/tools/miri/tests/fail/rc_as_ptr.rs
+++ b/src/tools/miri/tests/fail/rc_as_ptr.rs
@@ -16,5 +16,5 @@ fn main() {
     drop(strong);
     // But not any more. We can do Weak::as_raw(&weak), but accessing the pointer would lead to
     // undefined behaviour.
-    assert_eq!(42, **unsafe { &*Weak::as_ptr(&weak) }); //~ ERROR: dereferenced after this allocation got freed
+    assert_eq!(42, **unsafe { &*Weak::as_ptr(&weak) }); //~ ERROR: has been freed
 }
diff --git a/src/tools/miri/tests/fail/rc_as_ptr.stderr b/src/tools/miri/tests/fail/rc_as_ptr.stderr
index 70bdd157bdc..129916ac73c 100644
--- a/src/tools/miri/tests/fail/rc_as_ptr.stderr
+++ b/src/tools/miri/tests/fail/rc_as_ptr.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: pointer to ALLOC was dereferenced after this allocation got freed
+error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
   --> $DIR/rc_as_ptr.rs:LL:CC
    |
 LL |     assert_eq!(42, **unsafe { &*Weak::as_ptr(&weak) });
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pointer to ALLOC was dereferenced after this allocation got freed
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
diff --git a/src/tools/miri/tests/fail/shims/mmap_use_after_munmap.rs b/src/tools/miri/tests/fail/shims/mmap_use_after_munmap.rs
index 1e00bc6b64f..c97b013ba5a 100644
--- a/src/tools/miri/tests/fail/shims/mmap_use_after_munmap.rs
+++ b/src/tools/miri/tests/fail/shims/mmap_use_after_munmap.rs
@@ -14,6 +14,6 @@ fn main() {
             0,
         );
         libc::munmap(ptr, 4096);
-        let _x = *(ptr as *mut u8); //~ ERROR: was dereferenced after this allocation got freed
+        let _x = *(ptr as *mut u8); //~ ERROR: has been freed
     }
 }
diff --git a/src/tools/miri/tests/fail/shims/mmap_use_after_munmap.stderr b/src/tools/miri/tests/fail/shims/mmap_use_after_munmap.stderr
index f90701d400c..8b9969da8fd 100644
--- a/src/tools/miri/tests/fail/shims/mmap_use_after_munmap.stderr
+++ b/src/tools/miri/tests/fail/shims/mmap_use_after_munmap.stderr
@@ -13,11 +13,11 @@ LL |         libc::munmap(ptr, 4096);
    = note: BACKTRACE:
    = note: inside `main` at $DIR/mmap_use_after_munmap.rs:LL:CC
 
-error: Undefined Behavior: pointer to ALLOC was dereferenced after this allocation got freed
+error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
   --> $DIR/mmap_use_after_munmap.rs:LL:CC
    |
 LL |         let _x = *(ptr as *mut u8);
-   |                  ^^^^^^^^^^^^^^^^^ pointer to ALLOC was dereferenced after this allocation got freed
+   |                  ^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
diff --git a/src/tools/miri/tests/fail/zst2.rs b/src/tools/miri/tests/fail/zst2.rs
index 1d3e8ea9d00..04218c264a3 100644
--- a/src/tools/miri/tests/fail/zst2.rs
+++ b/src/tools/miri/tests/fail/zst2.rs
@@ -8,5 +8,5 @@ fn main() {
     let mut x_box = Box::new(1u8);
     let x = &mut *x_box as *mut _ as *mut [u8; 0];
     drop(x_box);
-    unsafe { *x = zst_val }; //~ ERROR: dereferenced after this allocation got freed
+    unsafe { *x = zst_val }; //~ ERROR: has been freed
 }
diff --git a/src/tools/miri/tests/fail/zst2.stderr b/src/tools/miri/tests/fail/zst2.stderr
index 6c49656e4c6..63f40ed2067 100644
--- a/src/tools/miri/tests/fail/zst2.stderr
+++ b/src/tools/miri/tests/fail/zst2.stderr
@@ -1,8 +1,8 @@
-error: Undefined Behavior: pointer to ALLOC was dereferenced after this allocation got freed
+error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
   --> $DIR/zst2.rs:LL:CC
    |
 LL |     unsafe { *x = zst_val };
-   |              ^^^^^^^^^^^^ pointer to ALLOC was dereferenced after this allocation got freed
+   |              ^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
diff --git a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.stderr b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.stderr
index 4eb1c42e1f7..b50ef0c68a1 100644
--- a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.stderr
+++ b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.stderr
@@ -2,13 +2,13 @@ error[E0080]: evaluation of constant value failed
   --> $DIR/dealloc_intrinsic_dangling.rs:10:5
    |
 LL |     &*ptr
-   |     ^^^^^ pointer to alloc2 was dereferenced after this allocation got freed
+   |     ^^^^^ dereferencing pointer failed: alloc2 has been freed, so this pointer is dangling
 
 error[E0080]: evaluation of constant value failed
   --> $DIR/dealloc_intrinsic_dangling.rs:18:5
    |
 LL |     *reference
-   |     ^^^^^^^^^^ pointer to alloc4 was dereferenced after this allocation got freed
+   |     ^^^^^^^^^^ dereferencing pointer failed: alloc4 has been freed, so this pointer is dangling
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_duplicate.stderr b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_duplicate.stderr
index 8177a08504b..0884ade45a7 100644
--- a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_duplicate.stderr
+++ b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_duplicate.stderr
@@ -2,7 +2,7 @@ error[E0080]: evaluation of constant value failed
   --> $DIR/dealloc_intrinsic_duplicate.rs:9:5
    |
 LL |     intrinsics::const_deallocate(ptr, 4, 4);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pointer to alloc2 was dereferenced after this allocation got freed
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: alloc2 has been freed, so this pointer is dangling
 
 error: aborting due to previous error
 
diff --git a/tests/ui/consts/const-eval/issue-49296.stderr b/tests/ui/consts/const-eval/issue-49296.stderr
index cc4f1594c32..45ba0ea183e 100644
--- a/tests/ui/consts/const-eval/issue-49296.stderr
+++ b/tests/ui/consts/const-eval/issue-49296.stderr
@@ -2,7 +2,7 @@ error[E0080]: evaluation of constant value failed
   --> $DIR/issue-49296.rs:9:16
    |
 LL | const X: u64 = *wat(42);
-   |                ^^^^^^^^ pointer to alloc3 was dereferenced after this allocation got freed
+   |                ^^^^^^^^ dereferencing pointer failed: alloc3 has been freed, so this pointer is dangling
 
 error: aborting due to previous error