When a nounwind function has a personality routine, LLVM messes up .seh directives (happens to rust_try in optimized builds). A workaround is to give rust_try the uwtable attribute.

Also, make sure that the dummy "load from null" instruction inserted by init_function() gets cleaned up.
This commit is contained in:
Vadim Chugunov 2015-08-01 16:07:38 -07:00
parent 6112b22078
commit e493027984

View file

@ -16,6 +16,7 @@ use llvm::{SequentiallyConsistent, Acquire, Release, AtomicXchg, ValueRef, TypeK
use middle::subst;
use middle::subst::FnSpace;
use trans::adt;
use trans::attributes;
use trans::base::*;
use trans::build::*;
use trans::callee;
@ -1189,6 +1190,7 @@ fn trans_gnu_try<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
// ret ptr
let rust_try = declare::define_internal_rust_fn(ccx, "__rust_try", try_fn_ty);
attributes::emit_uwtable(rust_try, true);
let catch_pers = match bcx.tcx().lang_items.eh_personality_catch() {
Some(did) => callee::trans_fn_ref(ccx, did, ExprId(0),
bcx.fcx.param_substs).val,
@ -1219,6 +1221,7 @@ fn trans_gnu_try<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
AddClause(catch, vals, C_null(Type::i8p(ccx)));
let ptr = ExtractValue(catch, vals, 0);
Ret(catch, ptr, dloc);
fcx.cleanup();
return rust_try
});