Rollup merge of #70375 - RalfJung:check-defined-err, r=oli-obk

avoid catching InterpError

Avoid raising and then capturing `InterpError` for the definedness check.

Cc https://github.com/rust-lang/rust/issues/69297
r? @oli-obk
This commit is contained in:
Mazdak Farrokhzad 2020-03-26 03:21:29 +01:00 committed by GitHub
commit ef01fe6bbc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -367,7 +367,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
let bytes = self.get_bytes_with_undef_and_ptr(cx, ptr, size)?;
// Undef check happens *after* we established that the alignment is correct.
// We must not return `Ok()` for unaligned pointers!
if self.check_defined(ptr, size).is_err() {
if self.is_defined(ptr, size).is_err() {
// This inflates undefined bytes to the entire scalar, even if only a few
// bytes are undefined.
return Ok(ScalarMaybeUndef::Undef);
@ -552,13 +552,19 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
}
/// Undefined bytes.
impl<'tcx, Tag, Extra> Allocation<Tag, Extra> {
impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
/// Checks whether the given range is entirely defined.
///
/// Returns `Ok(())` if it's defined. Otherwise returns the index of the byte
/// at which the first undefined access begins.
fn is_defined(&self, ptr: Pointer<Tag>, size: Size) -> Result<(), Size> {
self.undef_mask.is_range_defined(ptr.offset, ptr.offset + size) // `Size` addition
}
/// Checks that a range of bytes is defined. If not, returns the `ReadUndefBytes`
/// error which will report the first byte which is undefined.
#[inline]
fn check_defined(&self, ptr: Pointer<Tag>, size: Size) -> InterpResult<'tcx> {
self.undef_mask
.is_range_defined(ptr.offset, ptr.offset + size) // `Size` addition
self.is_defined(ptr, size)
.or_else(|idx| throw_ub!(InvalidUndefBytes(Some(Pointer::new(ptr.alloc_id, idx)))))
}