summary refs log tree commit diff
path: root/library/alloc/tests/vec_deque.rs
diff options
context:
space:
mode:
Diffstat (limited to 'library/alloc/tests/vec_deque.rs')
-rw-r--r--library/alloc/tests/vec_deque.rs161
1 files changed, 109 insertions, 52 deletions
diff --git a/library/alloc/tests/vec_deque.rs b/library/alloc/tests/vec_deque.rs
index 019d73c0b16..89cc7f905be 100644
--- a/library/alloc/tests/vec_deque.rs
+++ b/library/alloc/tests/vec_deque.rs
@@ -2,6 +2,7 @@ use std::assert_matches::assert_matches;
 use std::collections::TryReserveErrorKind::*;
 use std::collections::{vec_deque::Drain, VecDeque};
 use std::fmt::Debug;
+use std::mem::size_of;
 use std::ops::Bound::*;
 use std::panic::{catch_unwind, AssertUnwindSafe};
 
@@ -1160,6 +1161,12 @@ fn test_try_reserve() {
     const MAX_CAP: usize = (isize::MAX as usize + 1) / 2 - 1;
     const MAX_USIZE: usize = usize::MAX;
 
+    // On 16/32-bit, we check that allocations don't exceed isize::MAX,
+    // on 64-bit, we assume the OS will give an OOM for such a ridiculous size.
+    // Any platform that succeeds for these requests is technically broken with
+    // ptr::offset because LLVM is the worst.
+    let guards_against_isize = size_of::<usize>() < 8;
+
     {
         // Note: basic stuff is checked by test_reserve
         let mut empty_bytes: VecDeque<u8> = VecDeque::new();
@@ -1173,19 +1180,31 @@ fn test_try_reserve() {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
 
-        // Check isize::MAX + 1 does count as overflow
-        assert_matches!(
-            empty_bytes.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "isize::MAX + 1 should trigger an overflow!"
-        );
-
-        // Check usize::MAX does count as overflow
-        assert_matches!(
-            empty_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "usize::MAX should trigger an overflow!"
-        );
+        if guards_against_isize {
+            // Check isize::MAX + 1 does count as overflow
+            assert_matches!(
+                empty_bytes.try_reserve(MAX_CAP + 1).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
+
+            // Check usize::MAX does count as overflow
+            assert_matches!(
+                empty_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "usize::MAX should trigger an overflow!"
+            );
+        } else {
+            // Check isize::MAX is an OOM
+            // VecDeque starts with capacity 7, always adds 1 to the capacity
+            // and also rounds the number to next power of 2 so this is the
+            // furthest we can go without triggering CapacityOverflow
+            assert_matches!(
+                empty_bytes.try_reserve(MAX_CAP).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
+        }
     }
 
     {
@@ -1198,13 +1217,19 @@ fn test_try_reserve() {
         if let Err(CapacityOverflow) = ten_bytes.try_reserve(MAX_CAP - 10).map_err(|e| e.kind()) {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
-
-        assert_matches!(
-            ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "isize::MAX + 1 should trigger an overflow!"
-        );
-
+        if guards_against_isize {
+            assert_matches!(
+                ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
+        } else {
+            assert_matches!(
+                ten_bytes.try_reserve(MAX_CAP - 9).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
+        }
         // Should always overflow in the add-to-len
         assert_matches!(
             ten_bytes.try_reserve(MAX_USIZE).map_err(|e| e.kind()),
@@ -1225,13 +1250,19 @@ fn test_try_reserve() {
         {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
-
-        assert_matches!(
-            ten_u32s.try_reserve(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "isize::MAX + 1 should trigger an overflow!"
-        );
-
+        if guards_against_isize {
+            assert_matches!(
+                ten_u32s.try_reserve(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
+        } else {
+            assert_matches!(
+                ten_u32s.try_reserve(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
+        }
         // Should fail in the mul-by-size
         assert_matches!(
             ten_u32s.try_reserve(MAX_USIZE - 20).map_err(|e| e.kind()),
@@ -1251,6 +1282,8 @@ fn test_try_reserve_exact() {
     const MAX_CAP: usize = (isize::MAX as usize + 1) / 2 - 1;
     const MAX_USIZE: usize = usize::MAX;
 
+    let guards_against_isize = size_of::<usize>() < 8;
+
     {
         let mut empty_bytes: VecDeque<u8> = VecDeque::new();
 
@@ -1263,17 +1296,29 @@ fn test_try_reserve_exact() {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
 
-        assert_matches!(
-            empty_bytes.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "isize::MAX + 1 should trigger an overflow!"
-        );
-
-        assert_matches!(
-            empty_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "usize::MAX should trigger an overflow!"
-        );
+        if guards_against_isize {
+            assert_matches!(
+                empty_bytes.try_reserve_exact(MAX_CAP + 1).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
+
+            assert_matches!(
+                empty_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "usize::MAX should trigger an overflow!"
+            );
+        } else {
+            // Check isize::MAX is an OOM
+            // VecDeque starts with capacity 7, always adds 1 to the capacity
+            // and also rounds the number to next power of 2 so this is the
+            // furthest we can go without triggering CapacityOverflow
+            assert_matches!(
+                empty_bytes.try_reserve_exact(MAX_CAP).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
+        }
     }
 
     {
@@ -1289,13 +1334,19 @@ fn test_try_reserve_exact() {
         {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
-
-        assert_matches!(
-            ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "isize::MAX + 1 should trigger an overflow!"
-        );
-
+        if guards_against_isize {
+            assert_matches!(
+                ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
+        } else {
+            assert_matches!(
+                ten_bytes.try_reserve_exact(MAX_CAP - 9).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
+        }
         assert_matches!(
             ten_bytes.try_reserve_exact(MAX_USIZE).map_err(|e| e.kind()),
             Err(CapacityOverflow),
@@ -1316,13 +1367,19 @@ fn test_try_reserve_exact() {
         {
             panic!("isize::MAX shouldn't trigger an overflow!");
         }
-
-        assert_matches!(
-            ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
-            Err(CapacityOverflow),
-            "isize::MAX + 1 should trigger an overflow!"
-        );
-
+        if guards_against_isize {
+            assert_matches!(
+                ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+                Err(CapacityOverflow),
+                "isize::MAX + 1 should trigger an overflow!"
+            );
+        } else {
+            assert_matches!(
+                ten_u32s.try_reserve_exact(MAX_CAP / 4 - 9).map_err(|e| e.kind()),
+                Err(AllocError { .. }),
+                "isize::MAX + 1 should trigger an OOM!"
+            );
+        }
         assert_matches!(
             ten_u32s.try_reserve_exact(MAX_USIZE - 20).map_err(|e| e.kind()),
             Err(CapacityOverflow),