about summary refs log tree commit diff
diff options
context:
space:
mode:
authorScott McMurray <scottmcm@users.noreply.github.com>2022-04-09 16:29:39 -0700
committerScott McMurray <scottmcm@users.noreply.github.com>2022-05-11 17:16:25 -0700
commit4bb15b3797452b87c6ea3189fa60dd52d59a567d (patch)
tree194fa03722365a41d943b7ace70b38b3631cae0e
parente76b3f3b5b1bdb39d064a34f8c9a601633e749c2 (diff)
downloadrust-4bb15b3797452b87c6ea3189fa60dd52d59a567d.tar.gz
rust-4bb15b3797452b87c6ea3189fa60dd52d59a567d.zip
Add a debug check for ordering, and check for isize overflow in CTFE
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs13
-rw-r--r--library/core/src/ptr/const_ptr.rs4
2 files changed, 14 insertions, 3 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index f6dd02a9aba..3bb3b3d5393 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -365,10 +365,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                         } else {
                             usize_layout
                         };
-                        let a_offset = ImmTy::from_uint(a_offset.bytes(), usize_layout);
-                        let b_offset = ImmTy::from_uint(b_offset.bytes(), usize_layout);
-                        let (val, _overflowed, _ty) =
+
+                        // The subtraction is always done in `isize` to enforce
+                        // the "no more than `isize::MAX` apart" requirement.
+                        let a_offset = ImmTy::from_uint(a_offset.bytes(), isize_layout);
+                        let b_offset = ImmTy::from_uint(b_offset.bytes(), isize_layout);
+                        let (val, overflowed, _ty) =
                             self.overflowing_binary_op(BinOp::Sub, &a_offset, &b_offset)?;
+                        if overflowed {
+                            throw_ub_format!("Pointers were too far apart for {}", intrinsic_name);
+                        }
+
                         let pointee_layout = self.layout_of(substs.type_at(0))?;
                         let val = ImmTy::from_scalar(val, ret_layout);
                         let size = ImmTy::from_int(pointee_layout.size.bytes(), ret_layout);
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index 5be855bfabb..7fcdf21b03c 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -678,6 +678,10 @@ impl<T: ?Sized> *const T {
     where
         T: Sized,
     {
+        // SAFETY: The comparison has no side-effects, and the intrinsic
+        // does this check internally in the CTFE implementation.
+        unsafe { assert_unsafe_precondition!(self >= origin) };
+
         let pointee_size = mem::size_of::<T>();
         assert!(0 < pointee_size && pointee_size <= isize::MAX as usize);
         // SAFETY: the caller must uphold the safety contract for `ptr_offset_from_unsigned`.