Closed
Description
** UPDATE by @nikomatsakis **
This is almost-but-not-quite a dup of #8861, see this comment for details.
** ORIGINAL POST **
This program:
struct Foo { a: int }
impl Drop for Foo {
fn drop(&mut self) {
println!("{}", self.a);
}
}
fn main() {
{
let _1 = Foo { a: 1 };
let _2 = Foo { a: 2 };
match Foo { a: 3 } {
_ => {}
}
}
let _4 = Foo { a: 4 };
}
should output
3
2
1
4
but instead outputs
2
1
3
4
It appears that if the bare block around the first part of main
is removed, everything runs in the correct order. Moving the "3" Foo
into a variable also makes everything run in the right order.
This was originally reported to me in sfackler/rust-postgres#31 as a segfault, but it looks like that's probably just due to heap corruption from a use-after-free caused by this bug.
Update
IR:
join: ; preds = %case_body
call void @_ZN3Foo14glue_drop.146917h02f639dd107d06daE(%struct.Foo* %_2)
call void @_ZN3Foo14glue_drop.146917h02f639dd107d06daE(%struct.Foo* %_1)
call void @_ZN3Foo14glue_drop.146917h02f639dd107d06daE(%struct.Foo* %0) ; <-- 3
%7 = getelementptr inbounds %struct.Foo* %_4, i32 0, i32 1
store i8 1, i8* %7
%8 = getelementptr inbounds %struct.Foo* %_4, i32 0, i32 0
store i64 4, i64* %8
call void @_ZN3Foo14glue_drop.146917h02f639dd107d06daE(%struct.Foo* %_4)
ret void