From e6c7ce1b9eb809442661cb3673360e23ccdedfcd Mon Sep 17 00:00:00 2001 From: Jake Hughes Date: Mon, 14 Aug 2023 23:47:32 +0100 Subject: [PATCH] Zero vector contents after popping Since Alloy is a conservative GC, this prevents memory leaks kept alive by stale vector elements. --- library/alloc/src/vec/mod.rs | 4 ++- tests/ui/runtime/gc/zero_vecs.rs | 45 ++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 tests/ui/runtime/gc/zero_vecs.rs diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 89f069dc9a4f4..349a3b872fc46 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1955,7 +1955,9 @@ impl Vec { } else { unsafe { self.len -= 1; - Some(ptr::read(self.as_ptr().add(self.len()))) + let value = Some(ptr::read(self.as_ptr().add(self.len()))); + ptr::write_bytes(self.as_mut_ptr().add(self.len()), 0, 1); + value } } } diff --git a/tests/ui/runtime/gc/zero_vecs.rs b/tests/ui/runtime/gc/zero_vecs.rs new file mode 100644 index 0000000000000..4dba0a89d25ae --- /dev/null +++ b/tests/ui/runtime/gc/zero_vecs.rs @@ -0,0 +1,45 @@ +// run-pass +// ignore-tidy-linelength +#![feature(gc)] +#![feature(rustc_private)] +#![feature(negative_impls)] +#![feature(allocator_api)] +#![allow(unused_assignments)] +#![allow(unused_variables)] + +use std::gc::{Gc, GcAllocator}; +use std::sync::atomic::{self, AtomicUsize}; + +struct Finalizable(usize); + +impl Drop for Finalizable { + fn drop(&mut self) { + FINALIZER_COUNT.fetch_add(1, atomic::Ordering::Relaxed); + } +} + +static FINALIZER_COUNT: AtomicUsize = AtomicUsize::new(0); + +fn test_pop(v: &mut Vec, GcAllocator>) { + for i in 0..10 { + let mut gc = Some(Gc::new(Finalizable(i))); + v.push(gc.unwrap()); + gc = None; + } + + for _ in 0..10 { + let mut _gc = Some(v.pop()); + _gc = None; + } +} + +fn main() { + let mut v1 = Vec::with_capacity_in(10, GcAllocator); + test_pop(&mut v1); + test_pop(&mut v1); + + GcAllocator::force_gc(); + + assert_eq!(FINALIZER_COUNT.load(atomic::Ordering::Relaxed), 20); + +}