about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2020-03-26 03:21:29 +0100
committerGitHub <noreply@github.com>2020-03-26 03:21:29 +0100
commitef01fe6bbc0f675bb2795fb86113ae5ae0c92d3b (patch)
treed03f571f86c0efe065b966f9ea9d834fe0789f6b
parent9fa4953aa440cb85d13d6cc2a8a532a7d674cfa3 (diff)
parent0fdb7df32b0398f6cdac154c6c1c29e505147da6 (diff)
downloadrust-ef01fe6bbc0f675bb2795fb86113ae5ae0c92d3b.tar.gz
rust-ef01fe6bbc0f675bb2795fb86113ae5ae0c92d3b.zip
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
-rw-r--r--src/librustc/mir/interpret/allocation.rs16
1 files changed, 11 insertions, 5 deletions
diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs
index 26b9e1be2f5..ada02ceb5cb 100644
--- a/src/librustc/mir/interpret/allocation.rs
+++ b/src/librustc/mir/interpret/allocation.rs
@@ -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)))))
     }