diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_const_eval/messages.ftl | 2 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/errors.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/memory.rs | 23 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/step.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/interpret/error.rs | 4 |
5 files changed, 24 insertions, 16 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 { |
