mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-04 19:29:07 +00:00
Translation part of drop panic recovery
With this commit we now finally execute all the leftover drops once some drop panics for some reason!
This commit is contained in:
parent
98265d3385
commit
ebf6341d1d
@ -95,11 +95,36 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
|
||||
base::build_return_block(bcx.fcx, bcx, return_ty, DebugLoc::None);
|
||||
}
|
||||
|
||||
mir::Terminator::Drop { ref value, target, unwind: _ } => {
|
||||
mir::Terminator::Drop { ref value, target, unwind } => {
|
||||
let lvalue = self.trans_lvalue(bcx, value);
|
||||
// FIXME: this does not account for possibility of unwinding (and totally should).
|
||||
glue::drop_ty(bcx, lvalue.llval, lvalue.ty.to_ty(bcx.tcx()), DebugLoc::None);
|
||||
build::Br(bcx, self.llblock(target), DebugLoc::None);
|
||||
let ty = lvalue.ty.to_ty(bcx.tcx());
|
||||
// Double check for necessity to drop
|
||||
if !glue::type_needs_drop(bcx.tcx(), ty) {
|
||||
build::Br(bcx, self.llblock(target), DebugLoc::None);
|
||||
return;
|
||||
}
|
||||
let drop_fn = glue::get_drop_glue(bcx.ccx(), ty);
|
||||
let drop_ty = glue::get_drop_glue_type(bcx.ccx(), ty);
|
||||
let llvalue = if drop_ty != ty {
|
||||
build::PointerCast(bcx, lvalue.llval,
|
||||
type_of::type_of(bcx.ccx(), drop_ty).ptr_to())
|
||||
} else {
|
||||
lvalue.llval
|
||||
};
|
||||
if let Some(unwind) = unwind {
|
||||
let uwbcx = self.bcx(unwind);
|
||||
let unwind = self.make_landing_pad(uwbcx);
|
||||
build::Invoke(bcx,
|
||||
drop_fn,
|
||||
&[llvalue],
|
||||
self.llblock(target),
|
||||
unwind.llbb,
|
||||
None,
|
||||
DebugLoc::None);
|
||||
} else {
|
||||
build::Call(bcx, drop_fn, &[llvalue], None, DebugLoc::None);
|
||||
build::Br(bcx, self.llblock(target), DebugLoc::None);
|
||||
}
|
||||
}
|
||||
|
||||
mir::Terminator::Call { ref func, ref args, ref destination, ref cleanup } => {
|
||||
|
@ -65,7 +65,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
|
||||
assert!(lvalue.llextra != ptr::null_mut());
|
||||
lvalue.llextra
|
||||
}
|
||||
_ => bcx.sess().bug("unexpected type in get_base_and_len"),
|
||||
_ => bcx.sess().bug("unexpected type in lvalue_len"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,8 +195,8 @@ fn arg_value_refs<'bcx, 'tcx>(bcx: Block<'bcx, 'tcx>,
|
||||
mod analyze;
|
||||
mod block;
|
||||
mod constant;
|
||||
mod lvalue;
|
||||
mod rvalue;
|
||||
mod operand;
|
||||
mod statement;
|
||||
mod did;
|
||||
mod lvalue;
|
||||
mod operand;
|
||||
mod rvalue;
|
||||
mod statement;
|
||||
|
34
src/test/run-fail/mir_drop_panics.rs
Normal file
34
src/test/run-fail/mir_drop_panics.rs
Normal file
@ -0,0 +1,34 @@
|
||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
#![feature(rustc_attrs)]
|
||||
// error-pattern:panic 1
|
||||
// error-pattern:drop 2
|
||||
use std::io::{self, Write};
|
||||
|
||||
struct Droppable(u32);
|
||||
impl Drop for Droppable {
|
||||
fn drop(&mut self) {
|
||||
if self.0 == 1 {
|
||||
panic!("panic 1");
|
||||
} else {
|
||||
write!(io::stderr(), "drop {}", self.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[rustc_mir]
|
||||
fn mir() {
|
||||
let x = Droppable(2);
|
||||
let y = Droppable(1);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
mir();
|
||||
}
|
Loading…
Reference in New Issue
Block a user