Skip to content

Commit 7426252

Browse files
committed
Generate code properly for calls with _|_ - typed arguments
The code for translating a fail (for example) would call Unreachable(), which terminates the block; if a fail appeared as an argument, this would cause an LLVM assertion failure. Changed trans_call to handle this situation correctly.
1 parent f0fad0d commit 7426252

File tree

2 files changed

+34
-19
lines changed

2 files changed

+34
-19
lines changed

src/comp/middle/trans.rs

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5564,9 +5564,10 @@ fn trans_arg_expr(&@block_ctxt cx, &ty::arg arg, TypeRef lldestty0,
55645564
val = do_spill(lv.res.bcx, lv.res.val);
55655565
}
55665566
} else { auto re = trans_expr(bcx, e); val = re.val; bcx = re.bcx; }
5567+
auto is_bot = ty::type_is_bot(cx.fcx.lcx.ccx.tcx, e_ty);
55675568

55685569
// Make a copy here if the type is structural and we're passing by value.
5569-
if (arg.mode == ty::mo_val) {
5570+
if (arg.mode == ty::mo_val && !is_bot) {
55705571
if (ty::type_owns_heap_mem(cx.fcx.lcx.ccx.tcx, e_ty)) {
55715572
auto rslt = alloc_ty(bcx, e_ty);
55725573
bcx = rslt.bcx;
@@ -5579,7 +5580,7 @@ fn trans_arg_expr(&@block_ctxt cx, &ty::arg arg, TypeRef lldestty0,
55795580
}
55805581
}
55815582

5582-
if (ty::type_is_bot(cx.fcx.lcx.ccx.tcx, e_ty)) {
5583+
if (is_bot) {
55835584
// For values of type _|_, we generate an
55845585
// "undef" value, as such a value should never
55855586
// be inspected. It's important for the value
@@ -5747,25 +5748,30 @@ fn trans_call(&@block_ctxt cx, &@ast::expr f, &option::t[ValueRef] lliterbody,
57475748
}
57485749
*/
57495750

5750-
bcx.build.FastCall(faddr, llargs);
5751+
/* If the block is terminated,
5752+
then one or more of the args has
5753+
type _|_. Since that means it diverges, the code
5754+
for the call itself is unreachable. */
57515755
auto retval = C_nil();
5752-
alt (lliterbody) {
5753-
case (none) {
5754-
if (!ty::type_is_nil(cx.fcx.lcx.ccx.tcx, ret_ty)) {
5755-
retval = load_if_immediate(bcx, llretslot, ret_ty);
5756-
// Retval doesn't correspond to anything really tangible in
5757-
// the frame, but it's a ref all the same, so we put a note
5758-
// here to drop it when we're done in this scope.
5759-
5760-
find_scope_cx(cx).cleanups +=
5761-
[clean(bind drop_ty(_, retval, ret_ty))];
5756+
if (!bcx.build.is_terminated()) {
5757+
bcx.build.FastCall(faddr, llargs);
5758+
alt (lliterbody) {
5759+
case (none) {
5760+
if (!ty::type_is_nil(cx.fcx.lcx.ccx.tcx, ret_ty)) {
5761+
retval = load_if_immediate(bcx, llretslot, ret_ty);
5762+
// Retval doesn't correspond to anything really tangible
5763+
// in the frame, but it's a ref all the same, so we put a
5764+
// note here to drop it when we're done in this scope.
5765+
5766+
find_scope_cx(cx).cleanups +=
5767+
[clean(bind drop_ty(_, retval, ret_ty))];
5768+
}
5769+
}
5770+
case (some(_)) {
5771+
// If there was an lliterbody, it means we were calling an
5772+
// iter, and we are *not* the party using its 'output' value,
5773+
// we should ignore llretslot.
57625774
}
5763-
}
5764-
case (some(_)) {
5765-
// If there was an lliterbody, it means we were calling an
5766-
// iter, and we are *not* the party using its 'output' value,
5767-
// we should ignore llretslot.
5768-
57695775
}
57705776
}
57715777
ret rslt(bcx, retval);

src/test/run-fail/fail-arg.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// xfail-stage0
2+
// error-pattern:explicit failure
3+
fn f(int a) {
4+
log a;
5+
}
6+
7+
fn main() {
8+
f(fail);
9+
}

0 commit comments

Comments
 (0)