diff --git a/src/operator.rs b/src/operator.rs index 6e903a8f46..4662a16267 100644 --- a/src/operator.rs +++ b/src/operator.rs @@ -281,14 +281,6 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super: pointee_ty: Ty<'tcx>, offset: i64, ) -> EvalResult<'tcx, Scalar> { - if ptr.is_null() { - // NULL pointers must only be offset by 0 - return if offset == 0 { - Ok(ptr) - } else { - err!(InvalidNullPointerUsage) - }; - } // FIXME: assuming here that type size is < i64::max_value() let pointee_size = self.layout_of(pointee_ty)?.size.bytes() as i64; let offset = offset.checked_mul(pointee_size).ok_or_else(|| EvalErrorKind::Overflow(mir::BinOp::Mul))?; @@ -301,9 +293,13 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super: self.memory.check_bounds_ptr(ptr, false)?; Ok(Scalar::Ptr(ptr)) } else { - // An integer pointer. They can move around freely, as long as they do not overflow - // (which ptr_signed_offset checks). - ptr.ptr_signed_offset(offset, self) + // An integer pointer. They can only be offset by 0, and we pretend there + // is a little zero-sized allocation here. + if offset == 0 { + Ok(ptr) + } else { + err!(InvalidPointerMath) + } } } } diff --git a/tests/compile-fail/ptr_offset_int_plus_int.rs b/tests/compile-fail/ptr_offset_int_plus_int.rs new file mode 100644 index 0000000000..fa4efa3236 --- /dev/null +++ b/tests/compile-fail/ptr_offset_int_plus_int.rs @@ -0,0 +1,8 @@ +// error-pattern: invalid arithmetic on pointers + +fn main() { + // Can't offset an integer pointer by non-zero offset. + unsafe { + let _ = (1 as *mut u8).offset(1); + } +} diff --git a/tests/compile-fail/ptr_offset_ptr_plus_0.rs b/tests/compile-fail/ptr_offset_ptr_plus_0.rs new file mode 100644 index 0000000000..46937b1c8c --- /dev/null +++ b/tests/compile-fail/ptr_offset_ptr_plus_0.rs @@ -0,0 +1,7 @@ +// error-pattern: outside bounds of allocation + +fn main() { + let x = Box::into_raw(Box::new(0u32)); + let x = x.wrapping_offset(8); // okay, this has no inbounds tag + let _x = unsafe { x.offset(0) }; // UB despite offset 0, the pointer is not inbounds of the only object it can point to +}