about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-05-23 20:13:22 +0000
committerbors <bors@rust-lang.org>2018-05-23 20:13:22 +0000
commit29ffe51e34ec0491806befadc4f820b132b50f9e (patch)
tree34cb788ba7a0ab31506e0eab85767117c081ec39
parent27649b70327efd0613c8de01ff0b78205473a253 (diff)
parent9f79a1946a29110146364a7d8c12a2f8c8740262 (diff)
Auto merge of #50916 - oli-obk:miri, r=eddyb
Allow `Size` to be any valid `u64`

cc https://github.com/solson/miri/pull/378#issuecomment-390470725

The alternative is to make mir::interpret's pointer offsets not be `Size`

fixes #50917

r? @eddyb
-rw-r--r--src/librustc_target/abi/mod.rs43
1 files changed, 23 insertions, 20 deletions
diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs
index 2075400d04f..7f593aff21d 100644
--- a/src/librustc_target/abi/mod.rs
+++ b/src/librustc_target/abi/mod.rs
@@ -232,10 +232,7 @@ impl Size {
         Size::from_bytes(bits / 8 + ((bits % 8) + 7) / 8)
     }
 
-    pub fn from_bytes(bytes: u64) -> Size {
-        if bytes >= (1 << 61) {
-            panic!("Size::from_bytes: {} bytes in bits doesn't fit in u64", bytes)
-        }
+    pub const fn from_bytes(bytes: u64) -> Size {
         Size {
             raw: bytes
         }
@@ -246,7 +243,9 @@ impl Size {
     }
 
     pub fn bits(self) -> u64 {
-        self.bytes() * 8
+        self.bytes().checked_mul(8).unwrap_or_else(|| {
+            panic!("Size::bits: {} bytes in bits doesn't fit in u64", self.bytes())
+        })
     }
 
     pub fn abi_align(self, align: Align) -> Size {
@@ -262,9 +261,7 @@ impl Size {
     pub fn checked_add<C: HasDataLayout>(self, offset: Size, cx: C) -> Option<Size> {
         let dl = cx.data_layout();
 
-        // Each Size is less than dl.obj_size_bound(), so the sum is
-        // also less than 1 << 62 (and therefore can't overflow).
-        let bytes = self.bytes() + offset.bytes();
+        let bytes = self.bytes().checked_add(offset.bytes())?;
 
         if bytes < dl.obj_size_bound() {
             Some(Size::from_bytes(bytes))
@@ -276,11 +273,11 @@ impl Size {
     pub fn checked_mul<C: HasDataLayout>(self, count: u64, cx: C) -> Option<Size> {
         let dl = cx.data_layout();
 
-        match self.bytes().checked_mul(count) {
-            Some(bytes) if bytes < dl.obj_size_bound() => {
-                Some(Size::from_bytes(bytes))
-            }
-            _ => None
+        let bytes = self.bytes().checked_mul(count)?;
+        if bytes < dl.obj_size_bound() {
+            Some(Size::from_bytes(bytes))
+        } else {
+            None
         }
     }
 }
@@ -291,19 +288,25 @@ impl Size {
 impl Add for Size {
     type Output = Size;
     fn add(self, other: Size) -> Size {
-        // Each Size is less than 1 << 61, so the sum is
-        // less than 1 << 62 (and therefore can't overflow).
-        Size::from_bytes(self.bytes() + other.bytes())
+        Size::from_bytes(self.bytes().checked_add(other.bytes()).unwrap_or_else(|| {
+            panic!("Size::add: {} + {} doesn't fit in u64", self.bytes(), other.bytes())
+        }))
     }
 }
 
 impl Sub for Size {
     type Output = Size;
     fn sub(self, other: Size) -> Size {
-        // Each Size is less than 1 << 61, so an underflow
-        // would result in a value larger than 1 << 61,
-        // which Size::from_bytes will catch for us.
-        Size::from_bytes(self.bytes() - other.bytes())
+        Size::from_bytes(self.bytes().checked_sub(other.bytes()).unwrap_or_else(|| {
+            panic!("Size::sub: {} - {} would result in negative size", self.bytes(), other.bytes())
+        }))
+    }
+}
+
+impl Mul<Size> for u64 {
+    type Output = Size;
+    fn mul(self, size: Size) -> Size {
+        size * self
     }
 }