From ae950a2dc78e51493034f543184b1664647dd8e6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 14 Jul 2021 09:56:54 +0200 Subject: [PATCH] more precise message for the ptr access check on deref --- compiler/rustc_middle/src/mir/interpret/error.rs | 3 +++ compiler/rustc_middle/src/mir/interpret/mod.rs | 6 +++++- compiler/rustc_mir/src/interpret/place.rs | 15 +++++++-------- .../ui/consts/const-eval/ub-nonnull.32bit.stderr | 2 +- .../ui/consts/const-eval/ub-nonnull.64bit.stderr | 2 +- src/test/ui/consts/ptr_comparisons.stderr | 2 +- 6 files changed, 18 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 29caf01af1f..02a32b9fc6a 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -170,6 +170,8 @@ impl fmt::Display for InvalidProgramInfo<'_> { /// Details of why a pointer had to be in-bounds. #[derive(Debug, Copy, Clone, TyEncodable, TyDecodable, HashStable)] pub enum CheckInAllocMsg { + /// We are dereferencing a pointer (i.e., creating a place). + DerefTest, /// We are access memory. MemoryAccessTest, /// We are doing pointer arithmetic. @@ -186,6 +188,7 @@ impl fmt::Display for CheckInAllocMsg { f, "{}", match *self { + CheckInAllocMsg::DerefTest => "dereferencing pointer failed: ", CheckInAllocMsg::MemoryAccessTest => "memory access failed: ", CheckInAllocMsg::PointerArithmeticTest => "pointer arithmetic failed: ", CheckInAllocMsg::InboundsTest => "", diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 86bd35003bb..b05e3f5caa8 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -428,7 +428,11 @@ crate struct AllocMap<'tcx> { impl<'tcx> AllocMap<'tcx> { crate fn new() -> Self { - AllocMap { alloc_map: Default::default(), dedup: Default::default(), next_id: AllocId(NonZeroU64::new(1).unwrap()) } + AllocMap { + alloc_map: Default::default(), + dedup: Default::default(), + next_id: AllocId(NonZeroU64::new(1).unwrap()), + } } fn reserve(&mut self) -> AllocId { let next = self.next_id; diff --git a/compiler/rustc_mir/src/interpret/place.rs b/compiler/rustc_mir/src/interpret/place.rs index 5e35a83a5b9..1c9905b775f 100644 --- a/compiler/rustc_mir/src/interpret/place.rs +++ b/compiler/rustc_mir/src/interpret/place.rs @@ -373,7 +373,7 @@ where let val = self.read_immediate(src)?; trace!("deref to {} on {:?}", val.layout.ty, *val); let mplace = self.ref_to_mplace(&val)?; - self.check_mplace_access(mplace)?; + self.check_mplace_access(mplace, CheckInAllocMsg::DerefTest)?; Ok(mplace) } @@ -400,18 +400,17 @@ where } /// Check if this mplace is dereferencable and sufficiently aligned. - pub fn check_mplace_access(&self, mplace: MPlaceTy<'tcx, M::PointerTag>) -> InterpResult<'tcx> { + fn check_mplace_access( + &self, + mplace: MPlaceTy<'tcx, M::PointerTag>, + msg: CheckInAllocMsg, + ) -> InterpResult<'tcx> { let (size, align) = self .size_and_align_of_mplace(&mplace)? .unwrap_or((mplace.layout.size, mplace.layout.align.abi)); assert!(mplace.mplace.align <= align, "dynamic alignment less strict than static one?"); let align = M::enforce_alignment(&self.memory.extra).then_some(align); - self.memory.check_ptr_access_align( - mplace.ptr, - size, - align.unwrap_or(Align::ONE), - CheckInAllocMsg::MemoryAccessTest, // FIXME sth more specific? - )?; + self.memory.check_ptr_access_align(mplace.ptr, size, align.unwrap_or(Align::ONE), msg)?; Ok(()) } diff --git a/src/test/ui/consts/const-eval/ub-nonnull.32bit.stderr b/src/test/ui/consts/const-eval/ub-nonnull.32bit.stderr index a0f69d5d4cc..bebdd223975 100644 --- a/src/test/ui/consts/const-eval/ub-nonnull.32bit.stderr +++ b/src/test/ui/consts/const-eval/ub-nonnull.32bit.stderr @@ -13,7 +13,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/ub-nonnull.rs:19:30 | LL | let out_of_bounds_ptr = &ptr[255]; - | ^^^^^^^^ memory access failed: pointer must be in-bounds for 256 bytes at offset 0, but alloc11 has size 1 + | ^^^^^^^^ dereferencing pointer failed: pointer must be in-bounds for 256 bytes at offset 0, but alloc11 has size 1 error[E0080]: it is undefined behavior to use this value --> $DIR/ub-nonnull.rs:23:1 diff --git a/src/test/ui/consts/const-eval/ub-nonnull.64bit.stderr b/src/test/ui/consts/const-eval/ub-nonnull.64bit.stderr index d1c2025821c..0277506eff1 100644 --- a/src/test/ui/consts/const-eval/ub-nonnull.64bit.stderr +++ b/src/test/ui/consts/const-eval/ub-nonnull.64bit.stderr @@ -13,7 +13,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/ub-nonnull.rs:19:30 | LL | let out_of_bounds_ptr = &ptr[255]; - | ^^^^^^^^ memory access failed: pointer must be in-bounds for 256 bytes at offset 0, but alloc11 has size 1 + | ^^^^^^^^ dereferencing pointer failed: pointer must be in-bounds for 256 bytes at offset 0, but alloc11 has size 1 error[E0080]: it is undefined behavior to use this value --> $DIR/ub-nonnull.rs:23:1 diff --git a/src/test/ui/consts/ptr_comparisons.stderr b/src/test/ui/consts/ptr_comparisons.stderr index 5c285e3fe7b..032b947b895 100644 --- a/src/test/ui/consts/ptr_comparisons.stderr +++ b/src/test/ui/consts/ptr_comparisons.stderr @@ -16,7 +16,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/ptr_comparisons.rs:64:33 | LL | unsafe { std::ptr::addr_of!((*(FOO as *const usize as *const [u8; 1000]))[999]) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: pointer must be in-bounds for 1000 bytes at offset 0, but alloc3 has size $WORD + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: pointer must be in-bounds for 1000 bytes at offset 0, but alloc3 has size $WORD error: any use of this value will cause an error --> $DIR/ptr_comparisons.rs:68:27