From a859ca5c87ddfaa635fb4cacf8a41e04fd9b02e8 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Fri, 13 Dec 2019 14:51:37 +0100 Subject: Fix `binary_heap::DrainSorted` drop leak on panics --- src/liballoc/tests/binary_heap.rs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'src/liballoc/tests') diff --git a/src/liballoc/tests/binary_heap.rs b/src/liballoc/tests/binary_heap.rs index f49ca713921..be5516f54f3 100644 --- a/src/liballoc/tests/binary_heap.rs +++ b/src/liballoc/tests/binary_heap.rs @@ -1,6 +1,8 @@ use std::collections::binary_heap::{Drain, PeekMut}; use std::collections::BinaryHeap; use std::iter::TrustedLen; +use std::panic::{catch_unwind, AssertUnwindSafe}; +use std::sync::atomic::{AtomicU32, Ordering}; #[test] fn test_iterator() { @@ -275,6 +277,37 @@ fn test_drain_sorted() { assert!(q.is_empty()); } +#[test] +fn test_drain_sorted_leak() { + static DROPS: AtomicU32 = AtomicU32::new(0); + + #[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] + struct D(u32, bool); + + impl Drop for D { + fn drop(&mut self) { + DROPS.fetch_add(1, Ordering::SeqCst); + + if self.1 { + panic!("panic in `drop`"); + } + } + } + + let mut q = BinaryHeap::from(vec![ + D(0, false), + D(1, false), + D(2, false), + D(3, true), + D(4, false), + D(5, false), + ]); + + catch_unwind(AssertUnwindSafe(|| drop(q.drain_sorted()))).ok(); + + assert_eq!(DROPS.load(Ordering::SeqCst), 6); +} + #[test] fn test_extend_ref() { let mut a = BinaryHeap::new(); -- cgit 1.4.1-3-g733a5