// Insert cleanup instructions into the cleanup block
let funclet = match val {
- UnwindKind::CleanupPad(_) => Funclet::msvc(cleanup.cleanup_pad(None, &[])),
- UnwindKind::LandingPad => Funclet::gnu(),
+ UnwindKind::CleanupPad(_) => Some(Funclet::new(cleanup.cleanup_pad(None, &[]))),
+ UnwindKind::LandingPad => None,
};
drop_val.trans(funclet.as_ref(), &cleanup);
}
impl Funclet {
- pub fn gnu() -> Option<Funclet> {
- None
- }
-
- pub fn msvc(cleanuppad: ValueRef) -> Option<Funclet> {
- Some(Funclet {
+ pub fn new(cleanuppad: ValueRef) -> Funclet {
+ Funclet {
cleanuppad: cleanuppad,
operand: OperandBundleDef::new("funclet", &[cleanuppad]),
- })
+ }
}
pub fn cleanuppad(&self) -> ValueRef {
debug!("llblock: creating cleanup trampoline for {:?}", target);
let name = &format!("{:?}_cleanup_trampoline_{:?}", bb, target);
let trampoline = this.fcx.build_new_block(name);
- trampoline.set_personality_fn(this.fcx.eh_personality());
trampoline.cleanup_ret(cp, Some(lltarget));
trampoline.llbb()
}
if let Some(cleanup_pad) = cleanup_pad {
bcx.cleanup_ret(cleanup_pad, None);
} else {
- let llpersonality = bcx.fcx().eh_personality();
- bcx.set_personality_fn(llpersonality);
-
let ps = self.get_personality_slot(&bcx);
let lp = bcx.load(ps);
Lifetime::End.call(&bcx, ps);
// If false, all funclets should be None (which is the default)
let funclets: IndexVec<mir::BasicBlock, Option<Funclet>> =
mircx.cleanup_kinds.iter_enumerated().map(|(bb, cleanup_kind)| {
- let bcx = mircx.build_block(bb);
- match *cleanup_kind {
- _ if !base::wants_msvc_seh(fcx.ccx.sess()) => None,
- CleanupKind::Internal { .. } => {
- bcx.set_personality_fn(fcx.eh_personality());
- None
+ if let CleanupKind::Funclet = *cleanup_kind {
+ let bcx = mircx.build_block(bb);
+ bcx.set_personality_fn(fcx.eh_personality());
+ if base::wants_msvc_seh(fcx.ccx.sess()) {
+ return Some(Funclet::new(bcx.cleanup_pad(None, &[])));
}
- CleanupKind::Funclet => {
- bcx.set_personality_fn(fcx.eh_personality());
- Funclet::msvc(bcx.cleanup_pad(None, &[]))
- }
- _ => None
}
+
+ None
}).collect();
let rpo = traversal::reverse_postorder(&mir);