diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl index 671c2be1de9d2..2905874eec5f1 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 e1109e584b7bf..8cbc68d906140 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 02d022a2252a1..940a312d03baa 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( &self, ptr: Pointer>, @@ -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 91341ddacd107..59285a339afbd 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 d44dfa2172adc..eaa6c0ce2d672 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 8059fddb1008a..e929091b39661 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> { 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 9073f6954429a..b2dbe8a70f0f6 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 f07bbda4a9be9..7a3ff84b2cb13 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 fa7a74ee13cfe..23d145e7d30cd 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 3ad56da2c2fff..ecdd3ae5fee75 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 5631dcb4cc084..7c7cec211b76f 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 130e2a8301e1c..622348ad190d1 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 b1460bfb763ee..9c22215471635 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 d89c670b632e6..d5e6d37226ab3 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 cc3e56398781b..0cb8aa29001f3 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 4249c1cbf0177..49f3ae306a076 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 5f081afe68af8..398f216e73164 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 ad2a599b60b48..675e3e15da8c6 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 cb323818845df..cb95d71a605c0 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 0000000000000..65eca07a0708c --- /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 0000000000000..85bd2bed9c3b8 --- /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 similarity index 80% rename from src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.rs rename to src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_project_underscore.rs index 7c5f440b774f2..4c6412439507d 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 similarity index 55% rename from src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.stderr rename to src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_project_underscore.stderr index 7b76389c75359..f2d58fe769708 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 e749eb896e241..a1fefe04ab69c 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 02db6302a0a1e..c15f17f3b82ff 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 c193d5fe0b31e..5f8a1988b3c10 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 679e4809ca663..500f28a3cbc75 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 5d7a0cc1dc93e..c921ce6b71651 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 `` and (2) Read on thread `` // 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 f303d57c8bd9c..4efc35c15e2dc 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 a7f43f03c0258..e01132202d49e 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 `` and (2) Write on thread `` // 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 23b8e9ade0e0e..fad525830e644 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 e4597140b8440..6dcf1fdb1c7d3 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 a2d343bf8651c..6332846d5d8d1 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 29dc6e56f7c36..33348ace9c41d 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 { *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 80c5794736a9f..3eb17f0558465 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 6aea1870748cc..ebcf49b8f99e7 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 70bdd157bdc34..129916ac73c78 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 1e00bc6b64f96..c97b013ba5a34 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 f90701d400cac..8b9969da8fdb6 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 1d3e8ea9d007e..04218c264a3ef 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 6c49656e4c67d..63f40ed20674a 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 4eb1c42e1f767..b50ef0c68a155 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 8177a08504b0b..0884ade45a7e0 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 cc4f1594c32ec..45ba0ea183ec1 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