From 71ef8414bd86cbd79b29f8b1a0145da96e2f2f09 Mon Sep 17 00:00:00 2001 From: Joe Richey Date: Tue, 26 May 2020 02:00:02 -0700 Subject: 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 --- src/librustc_mir/interpret/intrinsics.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/librustc_mir') 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> { + // 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, -- cgit 1.4.1-3-g733a5