about summary refs log tree commit diff
path: root/src/librustc_mir
diff options
context:
space:
mode:
authorJoe Richey <joerichey@google.com>2020-05-26 02:00:02 -0700
committerJoe Richey <joerichey@google.com>2020-05-26 02:06:18 -0700
commit71ef8414bd86cbd79b29f8b1a0145da96e2f2f09 (patch)
tree2b38328d2118540ee6bef35088a29382b4ea985c /src/librustc_mir
parent6367b544b781889abee296d34d2b7d353a6ae0f8 (diff)
downloadrust-71ef8414bd86cbd79b29f8b1a0145da96e2f2f09.tar.gz
rust-71ef8414bd86cbd79b29f8b1a0145da96e2f2f09.zip
Add checks and tests for computing abs(offset_bytes)
The previous code paniced if offset_bytes == i64::MIN. This commit:
  - Properly computes the absoulte value to avoid this panic
  - Adds a test for this edge case

Signed-off-by: Joe Richey <joerichey@google.com>
Diffstat (limited to 'src/librustc_mir')
-rw-r--r--src/librustc_mir/interpret/intrinsics.rs5
1 files changed, 3 insertions, 2 deletions
diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs
index b4748059262..239115076bc 100644
--- a/src/librustc_mir/interpret/intrinsics.rs
+++ b/src/librustc_mir/interpret/intrinsics.rs
@@ -7,7 +7,7 @@ use std::convert::TryFrom;
 use rustc_hir::def_id::DefId;
 use rustc_middle::mir::{
     self,
-    interpret::{ConstValue, GlobalId, InterpResult, Scalar},
+    interpret::{uabs, ConstValue, GlobalId, InterpResult, Scalar},
     BinOp,
 };
 use rustc_middle::ty;
@@ -438,6 +438,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         pointee_ty: Ty<'tcx>,
         offset_count: i64,
     ) -> InterpResult<'tcx, Scalar<M::PointerTag>> {
+        // We cannot overflow i64 as a type's size must be <= isize::MAX.
         let pointee_size = i64::try_from(self.layout_of(pointee_ty)?.size.bytes()).unwrap();
         // The computed offset, in bytes, cannot overflow an isize.
         let offset_bytes = offset_count
@@ -450,7 +451,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         // memory between these pointers must be accessible. Note that we do not require the
         // pointers to be properly aligned (unlike a read/write operation).
         let min_ptr = if offset_bytes >= 0 { ptr } else { offset_ptr };
-        let size = offset_bytes.checked_abs().unwrap();
+        let size: u64 = uabs(offset_bytes);
         // This call handles checking for integer/NULL pointers.
         self.memory.check_ptr_access_align(
             min_ptr,