Skip to content

Commit 6a9e68a

Browse files
committed
Expand dynamic drop tests for cases in rust-lang#47949
1 parent aee7012 commit 6a9e68a

File tree

1 file changed

+91
-1
lines changed

1 file changed

+91
-1
lines changed

src/test/run-pass/drop/dynamic-drop.rs

+91-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ impl Allocator {
4141
data: RefCell::new(vec![])
4242
}
4343
}
44-
fn alloc(&self) -> Ptr {
44+
fn alloc(&self) -> Ptr<'_> {
4545
self.cur_ops.set(self.cur_ops.get() + 1);
4646

4747
if self.cur_ops.get() == self.failing_op {
@@ -53,6 +53,20 @@ impl Allocator {
5353
data.push(true);
5454
Ptr(addr, self)
5555
}
56+
// FIXME(#47949) Any use of this indicates a bug in rustc: we should never
57+
// be leaking values in the cases here.
58+
//
59+
// Creates a `Ptr<'_>` and checks that the allocated value is leaked if the
60+
// `failing_op` is in the list of exception.
61+
fn alloc_leaked(&self, exceptions: Vec<usize>) -> Ptr<'_> {
62+
let ptr = self.alloc();
63+
64+
if exceptions.iter().any(|operation| *operation == self.failing_op) {
65+
let mut data = self.data.borrow_mut();
66+
data[ptr.0] = false;
67+
}
68+
ptr
69+
}
5670
}
5771

5872
struct Ptr<'a>(usize, &'a Allocator);
@@ -255,6 +269,72 @@ fn subslice_pattern_reassign(a: &Allocator) {
255269
let[_, _y..] = ar;
256270
}
257271

272+
fn panic_after_return(a: &Allocator) -> Ptr<'_> {
273+
// Panic in the drop of `p` or `q` can leak
274+
let exceptions = vec![8, 9];
275+
a.alloc();
276+
let p = a.alloc();
277+
{
278+
a.alloc();
279+
let p = a.alloc();
280+
// FIXME (#47949) We leak values when we panic in a destructor after
281+
// evaluating an expression with `rustc_mir::build::Builder::into`.
282+
a.alloc_leaked(exceptions)
283+
}
284+
}
285+
286+
fn panic_after_return_expr(a: &Allocator) -> Ptr<'_> {
287+
// Panic in the drop of `p` or `q` can leak
288+
let exceptions = vec![8, 9];
289+
a.alloc();
290+
let p = a.alloc();
291+
{
292+
a.alloc();
293+
let q = a.alloc();
294+
// FIXME (#47949)
295+
return a.alloc_leaked(exceptions);
296+
}
297+
}
298+
299+
fn panic_after_init(a: &Allocator) {
300+
// Panic in the drop of `r` can leak
301+
let exceptions = vec![8];
302+
a.alloc();
303+
let p = a.alloc();
304+
let q = {
305+
a.alloc();
306+
let r = a.alloc();
307+
// FIXME (#47949)
308+
a.alloc_leaked(exceptions)
309+
};
310+
}
311+
312+
fn panic_after_init_temp(a: &Allocator) {
313+
// Panic in the drop of `r` can leak
314+
let exceptions = vec![8];
315+
a.alloc();
316+
let p = a.alloc();
317+
{
318+
a.alloc();
319+
let r = a.alloc();
320+
// FIXME (#47949)
321+
a.alloc_leaked(exceptions)
322+
};
323+
}
324+
325+
fn panic_after_init_by_loop(a: &Allocator) {
326+
// Panic in the drop of `r` can leak
327+
let exceptions = vec![8];
328+
a.alloc();
329+
let p = a.alloc();
330+
let q = loop {
331+
a.alloc();
332+
let r = a.alloc();
333+
// FIXME (#47949)
334+
break a.alloc_leaked(exceptions);
335+
};
336+
}
337+
258338
fn run_test<F>(mut f: F)
259339
where F: FnMut(&Allocator)
260340
{
@@ -342,5 +422,15 @@ fn main() {
342422
run_test(|a| slice_pattern_reassign(a));
343423
run_test(|a| subslice_pattern_reassign(a));
344424

425+
run_test(|a| {
426+
panic_after_return(a);
427+
});
428+
run_test(|a| {
429+
panic_after_return_expr(a);
430+
});
431+
run_test(|a| panic_after_init(a));
432+
run_test(|a| panic_after_init_temp(a));
433+
run_test(|a| panic_after_init_by_loop(a));
434+
345435
run_test_nopanic(|a| union1(a));
346436
}

0 commit comments

Comments
 (0)