Skip to content

Commit 4bb15b3

Browse files
committed
Add a debug check for ordering, and check for isize overflow in CTFE
1 parent e76b3f3 commit 4bb15b3

File tree

2 files changed

+14
-3
lines changed

2 files changed

+14
-3
lines changed

compiler/rustc_const_eval/src/interpret/intrinsics.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -365,10 +365,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
365365
} else {
366366
usize_layout
367367
};
368-
let a_offset = ImmTy::from_uint(a_offset.bytes(), usize_layout);
369-
let b_offset = ImmTy::from_uint(b_offset.bytes(), usize_layout);
370-
let (val, _overflowed, _ty) =
368+
369+
// The subtraction is always done in `isize` to enforce
370+
// the "no more than `isize::MAX` apart" requirement.
371+
let a_offset = ImmTy::from_uint(a_offset.bytes(), isize_layout);
372+
let b_offset = ImmTy::from_uint(b_offset.bytes(), isize_layout);
373+
let (val, overflowed, _ty) =
371374
self.overflowing_binary_op(BinOp::Sub, &a_offset, &b_offset)?;
375+
if overflowed {
376+
throw_ub_format!("Pointers were too far apart for {}", intrinsic_name);
377+
}
378+
372379
let pointee_layout = self.layout_of(substs.type_at(0))?;
373380
let val = ImmTy::from_scalar(val, ret_layout);
374381
let size = ImmTy::from_int(pointee_layout.size.bytes(), ret_layout);

library/core/src/ptr/const_ptr.rs

+4
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,10 @@ impl<T: ?Sized> *const T {
678678
where
679679
T: Sized,
680680
{
681+
// SAFETY: The comparison has no side-effects, and the intrinsic
682+
// does this check internally in the CTFE implementation.
683+
unsafe { assert_unsafe_precondition!(self >= origin) };
684+
681685
let pointee_size = mem::size_of::<T>();
682686
assert!(0 < pointee_size && pointee_size <= isize::MAX as usize);
683687
// SAFETY: the caller must uphold the safety contract for `ptr_offset_from_unsigned`.

0 commit comments

Comments
 (0)