Skip to content

Commit

Permalink
more precise message for the ptr access check on deref
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Jul 14, 2021
1 parent 4ff353c commit ae950a2
Show file tree
Hide file tree
Showing 6 changed files with 18 additions and 12 deletions.
3 changes: 3 additions & 0 deletions compiler/rustc_middle/src/mir/interpret/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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 => "",
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_middle/src/mir/interpret/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
15 changes: 7 additions & 8 deletions compiler/rustc_mir/src/interpret/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand All @@ -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(())
}

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/consts/const-eval/ub-nonnull.32bit.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/consts/const-eval/ub-nonnull.64bit.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/consts/ptr_comparisons.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit ae950a2

Please sign in to comment.