diff options
| author | bors <bors@rust-lang.org> | 2020-02-26 12:48:53 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-02-26 12:48:53 +0000 |
| commit | 892cb143e5984f220e6b26b48d972bd1f4644298 (patch) | |
| tree | 196b7add117dcb113ed0935e589060720f89ab84 /src/liballoc/tests/btree | |
| parent | 3a0d106109d73ed2e45a9925a9512ade2afb7df9 (diff) | |
| parent | e5987a062f487321bdfcbbdac4b0b30548258631 (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.rs | 28 |
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); +} |
