diff --git a/tests/mir-opt/box_conditional_drop_allocator.main.ElaborateDrops.diff b/tests/mir-opt/box_conditional_drop_allocator.main.ElaborateDrops.diff new file mode 100644 index 0000000000000..a190feb6d10f5 --- /dev/null +++ b/tests/mir-opt/box_conditional_drop_allocator.main.ElaborateDrops.diff @@ -0,0 +1,174 @@ +- // MIR for `main` before ElaborateDrops ++ // MIR for `main` after ElaborateDrops + + fn main() -> () { + let mut _0: (); + let _1: std::boxed::Box; + let mut _2: HasDrop; + let mut _3: DropAllocator; + let mut _4: bool; + let _5: (); + let mut _6: HasDrop; + let _7: (); + let mut _8: std::boxed::Box; ++ let mut _9: bool; ++ let mut _10: &mut std::boxed::Box; ++ let mut _11: (); ++ let mut _12: &mut std::boxed::Box; ++ let mut _13: (); ++ let mut _14: &mut std::boxed::Box; ++ let mut _15: (); + scope 1 { + debug b => _1; + } + + bb0: { ++ _9 = const false; + StorageLive(_1); + StorageLive(_2); + _2 = HasDrop; + StorageLive(_3); + _3 = DropAllocator; + _1 = Box::::new_in(move _2, move _3) -> [return: bb1, unwind: bb11]; + } + + bb1: { ++ _9 = const true; + StorageDead(_3); + StorageDead(_2); + StorageLive(_4); + _4 = const true; + switchInt(move _4) -> [0: bb4, otherwise: bb2]; + } + + bb2: { + StorageLive(_5); + StorageLive(_6); + _6 = move (*_1); + _5 = std::mem::drop::(move _6) -> [return: bb3, unwind: bb9]; + } + + bb3: { + StorageDead(_6); + StorageDead(_5); + _0 = const (); + goto -> bb6; + } + + bb4: { + StorageLive(_7); + StorageLive(_8); ++ _9 = const false; + _8 = move _1; + _7 = std::mem::drop::>(move _8) -> [return: bb5, unwind: bb8]; + } + + bb5: { + StorageDead(_8); + StorageDead(_7); + _0 = const (); + goto -> bb6; + } + + bb6: { + StorageDead(_4); +- drop(_1) -> [return: bb7, unwind continue]; ++ goto -> bb22; + } + + bb7: { ++ _9 = const false; + StorageDead(_1); + return; + } + + bb8 (cleanup): { +- drop(_8) -> [return: bb10, unwind terminate(cleanup)]; ++ goto -> bb10; + } + + bb9 (cleanup): { +- drop(_6) -> [return: bb10, unwind terminate(cleanup)]; ++ goto -> bb10; + } + + bb10 (cleanup): { +- drop(_1) -> [return: bb13, unwind terminate(cleanup)]; ++ goto -> bb27; + } + + bb11 (cleanup): { +- drop(_3) -> [return: bb12, unwind terminate(cleanup)]; ++ goto -> bb12; + } + + bb12 (cleanup): { +- drop(_2) -> [return: bb13, unwind terminate(cleanup)]; ++ goto -> bb13; + } + + bb13 (cleanup): { + resume; ++ } ++ ++ bb14: { ++ _9 = const false; ++ goto -> bb7; ++ } ++ ++ bb15 (cleanup): { ++ drop((_1.1: DropAllocator)) -> [return: bb13, unwind terminate(cleanup)]; ++ } ++ ++ bb16 (cleanup): { ++ switchInt(copy _9) -> [0: bb13, otherwise: bb15]; ++ } ++ ++ bb17: { ++ drop((_1.1: DropAllocator)) -> [return: bb14, unwind: bb13]; ++ } ++ ++ bb18: { ++ switchInt(copy _9) -> [0: bb14, otherwise: bb17]; ++ } ++ ++ bb19: { ++ _10 = &mut _1; ++ _11 = as Drop>::drop(move _10) -> [return: bb18, unwind: bb16]; ++ } ++ ++ bb20 (cleanup): { ++ _12 = &mut _1; ++ _13 = as Drop>::drop(move _12) -> [return: bb16, unwind terminate(cleanup)]; ++ } ++ ++ bb21: { ++ goto -> bb19; ++ } ++ ++ bb22: { ++ switchInt(copy _9) -> [0: bb7, otherwise: bb21]; ++ } ++ ++ bb23 (cleanup): { ++ drop((_1.1: DropAllocator)) -> [return: bb13, unwind terminate(cleanup)]; ++ } ++ ++ bb24 (cleanup): { ++ switchInt(copy _9) -> [0: bb13, otherwise: bb23]; ++ } ++ ++ bb25 (cleanup): { ++ _14 = &mut _1; ++ _15 = as Drop>::drop(move _14) -> [return: bb24, unwind terminate(cleanup)]; ++ } ++ ++ bb26 (cleanup): { ++ goto -> bb25; ++ } ++ ++ bb27 (cleanup): { ++ switchInt(copy _9) -> [0: bb13, otherwise: bb26]; + } + } + diff --git a/tests/mir-opt/box_conditional_drop_allocator.rs b/tests/mir-opt/box_conditional_drop_allocator.rs new file mode 100644 index 0000000000000..b8a9d5e5c4c2e --- /dev/null +++ b/tests/mir-opt/box_conditional_drop_allocator.rs @@ -0,0 +1,38 @@ +// skip-filecheck +//@ test-mir-pass: ElaborateDrops +#![feature(allocator_api)] + +// Regression test for #131082. +// Testing that the allocator of a Box is dropped in conditional drops + +use std::alloc::{AllocError, Allocator, Global, Layout}; +use std::ptr::NonNull; + +struct DropAllocator; + +unsafe impl Allocator for DropAllocator { + fn allocate(&self, layout: Layout) -> Result, AllocError> { + Global.allocate(layout) + } + unsafe fn deallocate(&self, ptr: NonNull, layout: Layout) { + Global.deallocate(ptr, layout); + } +} +impl Drop for DropAllocator { + fn drop(&mut self) {} +} + +struct HasDrop; +impl Drop for HasDrop { + fn drop(&mut self) {} +} + +// EMIT_MIR box_conditional_drop_allocator.main.ElaborateDrops.diff +fn main() { + let b = Box::new_in(HasDrop, DropAllocator); + if true { + drop(*b); + } else { + drop(b); + } +}