diff options
| author | bors <bors@rust-lang.org> | 2021-07-20 08:15:15 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-07-20 08:15:15 +0000 |
| commit | 718d53b0cb7dde93499cb92950d60b412f5a3d05 (patch) | |
| tree | d0b67c2ac9d69e7760140c43a8464ac3233c3b59 /compiler/rustc_middle | |
| parent | a72c360a30f9a8160e4f40340cecc9b1ce979cd7 (diff) | |
| parent | bed3b965aef7f3a3da789b4e0493fa77f75440de (diff) | |
| download | rust-718d53b0cb7dde93499cb92950d60b412f5a3d05.tar.gz rust-718d53b0cb7dde93499cb92950d60b412f5a3d05.zip | |
Auto merge of #87224 - RalfJung:miri-ptr-oob, r=oli-obk
miri: better ptr-out-of-bounds errors For offsets larger than `isize::MAX`, display them as negative offsets. r? `@oli-obk`
Diffstat (limited to 'compiler/rustc_middle')
| -rw-r--r-- | compiler/rustc_middle/src/mir/interpret/error.rs | 30 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/interpret/pointer.rs | 14 |
2 files changed, 30 insertions, 14 deletions
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 432d078dc9b..94ac303b109 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -240,12 +240,13 @@ pub enum UndefinedBehaviorInfo<'tcx> { /// Dereferencing a dangling pointer after it got freed. PointerUseAfterFree(AllocId), /// 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 { alloc_id: AllocId, - offset: Size, - size: Size, + alloc_size: Size, + ptr_offset: i64, + ptr_size: Size, msg: CheckInAllocMsg, - allocation_size: Size, }, /// Using an integer as a pointer in the wrong way. DanglingIntPointer(u64, CheckInAllocMsg), @@ -318,24 +319,25 @@ impl fmt::Display for UndefinedBehaviorInfo<'_> { PointerUseAfterFree(a) => { write!(f, "pointer to {} was dereferenced after this allocation got freed", a) } - PointerOutOfBounds { alloc_id, offset, size: Size::ZERO, msg, allocation_size } => { + PointerOutOfBounds { alloc_id, alloc_size, ptr_offset, ptr_size: Size::ZERO, msg } => { write!( f, - "{}{} has size {}, so pointer at offset {} is out-of-bounds", + "{}{alloc_id} has size {alloc_size}, so pointer at offset {ptr_offset} is out-of-bounds", msg, - alloc_id, - allocation_size.bytes(), - offset.bytes(), + alloc_id = alloc_id, + alloc_size = alloc_size.bytes(), + ptr_offset = ptr_offset, ) } - PointerOutOfBounds { alloc_id, offset, size, msg, allocation_size } => write!( + PointerOutOfBounds { alloc_id, alloc_size, ptr_offset, ptr_size, msg } => write!( f, - "{}{} has size {}, so pointer to {} bytes starting at offset {} is out-of-bounds", + "{}{alloc_id} has size {alloc_size}, so pointer to {ptr_size} byte{ptr_size_p} starting at offset {ptr_offset} is out-of-bounds", msg, - alloc_id, - allocation_size.bytes(), - size.bytes(), - offset.bytes(), + alloc_id = alloc_id, + alloc_size = alloc_size.bytes(), + ptr_size = ptr_size.bytes(), + ptr_size_p = pluralize!(ptr_size.bytes()), + ptr_offset = ptr_offset, ), DanglingIntPointer(0, CheckInAllocMsg::InboundsTest) => { write!(f, "null pointer is not a valid pointer for this operation") diff --git a/compiler/rustc_middle/src/mir/interpret/pointer.rs b/compiler/rustc_middle/src/mir/interpret/pointer.rs index 7e7a7119be6..568b3f252bf 100644 --- a/compiler/rustc_middle/src/mir/interpret/pointer.rs +++ b/compiler/rustc_middle/src/mir/interpret/pointer.rs @@ -36,6 +36,20 @@ pub trait PointerArithmetic: HasDataLayout { i64::try_from(max_isize_plus_1 - 1).unwrap() } + #[inline] + fn machine_usize_to_isize(&self, val: u64) -> i64 { + let val = val as i64; + // Now clamp into the machine_isize range. + if val > self.machine_isize_max() { + // This can only happen the the ptr size is < 64, so we know max_usize_plus_1 fits into + // i64. + let max_usize_plus_1 = 1u128 << self.pointer_size().bits(); + val - i64::try_from(max_usize_plus_1).unwrap() + } else { + val + } + } + /// Helper function: truncate given value-"overflowed flag" pair to pointer size and /// update "overflowed flag" if there was an overflow. /// This should be called by all the other methods before returning! |
