about summary refs log tree commit diff
path: root/src/liballoc/tests
diff options
context:
space:
mode:
authorJonas Schievink <jonasschievink@gmail.com>2019-12-13 18:36:35 +0100
committerJonas Schievink <jonasschievink@gmail.com>2020-01-19 20:24:08 +0100
commitdc492452dae29d75b14afe3559f5fb59be7f2d3a (patch)
tree3005b81d064c2a8bb8af93ac2cad49e126484292 /src/liballoc/tests
parent5d04790dd2e73f3faf08d528e3675e131585ec01 (diff)
downloadrust-dc492452dae29d75b14afe3559f5fb59be7f2d3a.tar.gz
rust-dc492452dae29d75b14afe3559f5fb59be7f2d3a.zip
Fix leak in btree_map::IntoIter when drop panics
Diffstat (limited to 'src/liballoc/tests')
-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 f5be72c39b2..0729f341d86 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;
 
@@ -980,3 +982,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);
+}