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`
This commit is contained in:
commit
718d53b0cb
5 changed files with 65 additions and 28 deletions
|
@ -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")
|
||||
|
|
|
@ -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!
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue