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
4 changed files with 68 additions and 9 deletions
|
@ -95,11 +95,36 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
|
||||||
base::build_return_block(bcx.fcx, bcx, return_ty, DebugLoc::None);
|
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);
|
let lvalue = self.trans_lvalue(bcx, value);
|
||||||
// FIXME: this does not account for possibility of unwinding (and totally should).
|
let ty = lvalue.ty.to_ty(bcx.tcx());
|
||||||
glue::drop_ty(bcx, lvalue.llval, lvalue.ty.to_ty(bcx.tcx()), DebugLoc::None);
|
// Double check for necessity to drop
|
||||||
build::Br(bcx, self.llblock(target), DebugLoc::None);
|
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 } => {
|
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());
|
assert!(lvalue.llextra != ptr::null_mut());
|
||||||
lvalue.llextra
|
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 analyze;
|
||||||
mod block;
|
mod block;
|
||||||
mod constant;
|
mod constant;
|
||||||
mod lvalue;
|
|
||||||
mod rvalue;
|
|
||||||
mod operand;
|
|
||||||
mod statement;
|
|
||||||
mod did;
|
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…
Add table
Add a link
Reference in a new issue