Skip to content

Commit 410f73f

Browse files
committed
Don't write to retptr when returning nil, pass undef for unused params
1 parent 68d50b5 commit 410f73f

File tree

1 file changed

+18
-15
lines changed

1 file changed

+18
-15
lines changed

src/comp/middle/trans.rs

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3351,8 +3351,7 @@ fn trans_bind_thunk(cx: @local_ctxt, sp: span, incoming_fty: ty::t,
33513351
// out the pointer to the target function from the environment. The
33523352
// target function lives in the first binding spot.
33533353
let (lltargetfn, lltargetenv, starting_idx) = alt target_fn {
3354-
some(fptr) { (fptr, null_env_ptr(bcx), 0)
3355-
}
3354+
some(fptr) { (fptr, llvm::LLVMGetUndef(T_opaque_closure_ptr(*ccx)), 0) }
33563355
none. {
33573356
// Silly check
33583357
check type_is_tup_like(bcx, closure_ty);
@@ -3646,12 +3645,7 @@ fn trans_args(cx: @block_ctxt, outer_cx: @block_ctxt, llenv: ValueRef,
36463645
to_zero: to_zero,
36473646
to_revoke: to_revoke};
36483647
}
3649-
let retty = ty::ty_fn_ret(tcx, fn_ty);
3650-
let llretslot_res = if by_ref {
3651-
rslt(cx, alloca(cx, T_ptr(type_of_or_i8(bcx, retty))))
3652-
} else { alloc_ty(bcx, retty) };
3653-
bcx = llretslot_res.bcx;
3654-
let llretslot = llretslot_res.val;
3648+
let retty = ty::ty_fn_ret(tcx, fn_ty), full_retty = retty;
36553649
alt gen {
36563650
some(g) {
36573651
lazily_emit_all_generic_info_tydesc_glues(cx, g);
@@ -3661,6 +3655,13 @@ fn trans_args(cx: @block_ctxt, outer_cx: @block_ctxt, llenv: ValueRef,
36613655
}
36623656
_ { }
36633657
}
3658+
let llretslot_res = if ty::type_is_nil(tcx, retty) {
3659+
rslt(cx, llvm::LLVMGetUndef(T_ptr(T_nil())))
3660+
} else if by_ref {
3661+
rslt(cx, alloca(cx, T_ptr(type_of_or_i8(bcx, full_retty))))
3662+
} else { alloc_ty(bcx, full_retty) };
3663+
bcx = llretslot_res.bcx;
3664+
let llretslot = llretslot_res.val;
36643665
if ty::type_contains_params(tcx, retty) {
36653666
// It's possible that the callee has some generic-ness somewhere in
36663667
// its return value -- say a method signature within an obj or a fn
@@ -3744,7 +3745,9 @@ fn trans_call(in_cx: @block_ctxt, f: @ast::expr,
37443745
let faddr = f_res.val;
37453746
let llenv;
37463747
alt f_res.env {
3747-
null_env. { llenv = null_env_ptr(cx); }
3748+
null_env. {
3749+
llenv = llvm::LLVMGetUndef(T_opaque_closure_ptr(*bcx_ccx(cx)));
3750+
}
37483751
some_env(e) { llenv = e; }
37493752
is_closure. {
37503753
// It's a closure. Have to fetch the elements
@@ -4570,7 +4573,9 @@ fn trans_ret(cx: @block_ctxt, e: option::t<@ast::expr>) -> result {
45704573
let t = ty::expr_ty(bcx_tcx(cx), x);
45714574
let lv = trans_lval(cx, x);
45724575
bcx = lv.bcx;
4573-
if ast_util::ret_by_ref(cx.fcx.ret_style) {
4576+
if ty::type_is_nil(bcx_tcx(cx), t) {
4577+
// Don't write nil
4578+
} else if ast_util::ret_by_ref(cx.fcx.ret_style) {
45744579
assert lv.is_mem;
45754580
Store(bcx, lv.val, cx.fcx.llretptr);
45764581
} else {
@@ -4590,10 +4595,7 @@ fn trans_ret(cx: @block_ctxt, e: option::t<@ast::expr>) -> result {
45904595
}
45914596
}
45924597
}
4593-
_ {
4594-
let t = llvm::LLVMGetElementType(val_ty(cx.fcx.llretptr));
4595-
Store(bcx, C_null(t), cx.fcx.llretptr);
4596-
}
4598+
_ {}
45974599
}
45984600
// run all cleanups and back out.
45994601

@@ -5280,7 +5282,8 @@ fn trans_closure(bcx_maybe: option::t<@block_ctxt>,
52805282
// (trans_block, trans_expr, et cetera).
52815283
let rslt =
52825284
if !ty::type_is_bot(cx.ccx.tcx, block_ty) &&
5283-
f.proto != ast::proto_iter {
5285+
!ty::type_is_nil(cx.ccx.tcx, block_ty) &&
5286+
f.proto != ast::proto_iter {
52845287
trans_block(bcx, f.body, save_in(fcx.llretptr))
52855288
} else { trans_block(bcx, f.body, return) };
52865289
bcx = rslt.bcx;

0 commit comments

Comments
 (0)