about summary refs log tree commit diff
path: root/src/liballoc/tests/btree
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-02-26 12:48:53 +0000
committerbors <bors@rust-lang.org>2020-02-26 12:48:53 +0000
commit892cb143e5984f220e6b26b48d972bd1f4644298 (patch)
tree196b7add117dcb113ed0935e589060720f89ab84 /src/liballoc/tests/btree
parent3a0d106109d73ed2e45a9925a9512ade2afb7df9 (diff)
parente5987a062f487321bdfcbbdac4b0b30548258631 (diff)
Auto merge of #67290 - jonas-schievink:leak-audit, r=KodrAus
Audit liballoc for leaks in `Drop` impls when user destructor panics

Inspired by https://github.com/rust-lang/rust/pull/67243 and https://github.com/rust-lang/rust/pull/67235, this audits and hopefully fixes the remaining `Drop` impls in liballoc for resource leaks in the presence of panics in destructors called by the affected `Drop` impl.

This does not touch `Hash{Map,Set}` since they live in hashbrown. They have similar issues though.

r? @KodrAus
Diffstat (limited to 'src/liballoc/tests/btree')
-rw-r--r--src/liballoc/tests/btree/map.rs28
1 files changed, 28 insertions, 0 deletions
diff --git a/src/liballoc/tests/btree/map.rs b/src/liballoc/tests/btree/map.rs
index 4a9af64f9d4..fd07a4d3926 100644
--- a/src/liballoc/tests/btree/map.rs
+++ b/src/liballoc/tests/btree/map.rs
@@ -5,7 +5,9 @@ use std::fmt::Debug;
 use std::iter::FromIterator;
 use std::ops::Bound::{self, Excluded, Included, Unbounded};
 use std::ops::RangeBounds;
+use std::panic::catch_unwind;
 use std::rc::Rc;
+use std::sync::atomic::{AtomicU32, Ordering};
 
 use super::DeterministicRng;
 
@@ -1017,3 +1019,29 @@ fn test_split_off_large_random_sorted() {
     assert!(map.into_iter().eq(data.clone().into_iter().filter(|x| x.0 < key)));
     assert!(right.into_iter().eq(data.into_iter().filter(|x| x.0 >= key)));
 }
+
+#[test]
+fn test_into_iter_drop_leak() {
+    static DROPS: AtomicU32 = AtomicU32::new(0);
+
+    struct D;
+
+    impl Drop for D {
+        fn drop(&mut self) {
+            if DROPS.fetch_add(1, Ordering::SeqCst) == 3 {
+                panic!("panic in `drop`");
+            }
+        }
+    }
+
+    let mut map = BTreeMap::new();
+    map.insert("a", D);
+    map.insert("b", D);
+    map.insert("c", D);
+    map.insert("d", D);
+    map.insert("e", D);
+
+    catch_unwind(move || drop(map.into_iter())).ok();
+
+    assert_eq!(DROPS.load(Ordering::SeqCst), 5);
+}