about summary refs log tree commit diff
path: root/src/liballoc/collections/btree
diff options
context:
space:
mode:
authorStein Somers <git@steinsomers.be>2020-03-06 14:32:54 +0100
committerStein Somers <git@steinsomers.be>2020-03-06 14:50:09 +0100
commit44c97c43b5d3df5d76381f80fb8ad0042c6ccf55 (patch)
tree98abd6c59b19239937f9c0d740aa8a894ae0b3fa /src/liballoc/collections/btree
parent865b44a3e330f3ef8be0f6edf69896c9ed957ac0 (diff)
downloadrust-44c97c43b5d3df5d76381f80fb8ad0042c6ccf55.tar.gz
rust-44c97c43b5d3df5d76381f80fb8ad0042c6ccf55.zip
Fix & test leak of some BTreeMap nodes on panic during `into_iter`
Diffstat (limited to 'src/liballoc/collections/btree')
-rw-r--r--src/liballoc/collections/btree/map.rs11
1 files changed, 10 insertions, 1 deletions
diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs
index 8b9ffdfb49b..9da324ba2d4 100644
--- a/src/liballoc/collections/btree/map.rs
+++ b/src/liballoc/collections/btree/map.rs
@@ -1477,6 +1477,14 @@ impl<K, V> Drop for IntoIter<K, V> {
                 // Continue the same loop we perform below. This only runs when unwinding, so we
                 // don't have to care about panics this time (they'll abort).
                 while let Some(_) = self.0.next() {}
+
+                // No need to avoid the shared root, because the tree was definitely not empty.
+                unsafe {
+                    let mut node = ptr::read(&self.0.front).into_node().forget_type();
+                    while let Some(parent) = node.deallocate_and_ascend() {
+                        node = parent.into_node().forget_type();
+                    }
+                }
             }
         }
 
@@ -1491,7 +1499,8 @@ impl<K, V> Drop for IntoIter<K, V> {
             if node.is_shared_root() {
                 return;
             }
-
+            // Most of the nodes have been deallocated while traversing
+            // but one pile from a leaf up to the root is left standing.
             while let Some(parent) = node.deallocate_and_ascend() {
                 node = parent.into_node().forget_type();
             }