about summary refs log tree commit diff
path: root/compiler/rustc_middle
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-07-20 08:15:15 +0000
committerbors <bors@rust-lang.org>2021-07-20 08:15:15 +0000
commit718d53b0cb7dde93499cb92950d60b412f5a3d05 (patch)
treed0b67c2ac9d69e7760140c43a8464ac3233c3b59 /compiler/rustc_middle
parenta72c360a30f9a8160e4f40340cecc9b1ce979cd7 (diff)
parentbed3b965aef7f3a3da789b4e0493fa77f75440de (diff)
downloadrust-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.rs30
-rw-r--r--compiler/rustc_middle/src/mir/interpret/pointer.rs14
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!