Skip to content

Commit ac5cc80

Browse files
committed
---
yaml --- r: 1957 b: refs/heads/master c: 125bebb h: refs/heads/master i: 1955: fb5880c v: v3
1 parent b8db6e8 commit ac5cc80

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: bd1c61548ec2ddde4d85dbef88eed6627b536d13
2+
refs/heads/master: 125bebbf60acf13bcbebaab2d68d2c68d5a06f77

trunk/src/comp/middle/trans.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,6 +1026,18 @@ fn find_scope_cx(@block_ctxt cx) -> @block_ctxt {
10261026
}
10271027
}
10281028

1029+
fn find_outer_scope_cx(@block_ctxt cx) -> @block_ctxt {
1030+
auto scope_cx = find_scope_cx(cx);
1031+
alt (cx.parent) {
1032+
case (parent_some(?b)) {
1033+
be find_scope_cx(b);
1034+
}
1035+
case (parent_none) {
1036+
fail;
1037+
}
1038+
}
1039+
}
1040+
10291041
fn umax(@block_ctxt cx, ValueRef a, ValueRef b) -> ValueRef {
10301042
auto cond = cx.build.ICmp(lib.llvm.LLVMIntULT, a, b);
10311043
ret cx.build.Select(cond, b, a);
@@ -5368,8 +5380,55 @@ fn trans_block(@block_ctxt cx, &ast.block b) -> result {
53685380
case (some[@ast.expr](?e)) {
53695381
r = trans_expr(bcx, e);
53705382
bcx = r.bcx;
5383+
53715384
if (is_terminated(bcx)) {
53725385
ret r;
5386+
} else {
5387+
// The value resulting from the block gets copied into an
5388+
// alloca created in an enclosing scope and it's refcount
5389+
// bumped so that it can escape this block. This means that
5390+
// it will definitely live until the end of the enclosing
5391+
// scope, even if nobody uses it, which may be something of
5392+
// a surprise.
5393+
5394+
auto r_ty = ty.expr_ty(e);
5395+
5396+
fn is_nil(@ty.t r_ty) -> bool {
5397+
alt (r_ty.struct) {
5398+
case (ty.ty_nil) {
5399+
ret true;
5400+
}
5401+
case (_) {
5402+
ret false;
5403+
}
5404+
}
5405+
}
5406+
5407+
// FIXME: This is a temporary hack to prevent compile
5408+
// failures. There's some expression variant that claims
5409+
// to be ty_nil but but does not translate to T_nil. Need
5410+
// to hunt it down.
5411+
if (!is_nil(r_ty)) {
5412+
// This alloca is declared at the function level, above
5413+
// the block scope
5414+
auto res_alloca = alloc_ty(bcx, r_ty);
5415+
bcx = res_alloca.bcx;
5416+
auto res_copy = copy_ty(bcx, INIT,
5417+
res_alloca.val, r.val, r_ty);
5418+
bcx = res_copy.bcx;
5419+
5420+
fn drop_hoisted_ty(@block_ctxt cx,
5421+
ValueRef alloca_val,
5422+
@ty.t t) -> result {
5423+
auto reg_val = load_scalar_or_boxed(cx,
5424+
alloca_val, t);
5425+
ret drop_ty(cx, reg_val, t);
5426+
}
5427+
5428+
auto cleanup = bind drop_hoisted_ty(_, res_alloca.val,
5429+
r_ty);
5430+
find_outer_scope_cx(bcx).cleanups += vec(clean(cleanup));
5431+
}
53735432
}
53745433
}
53755434
case (none[@ast.expr]) {

0 commit comments

Comments
 (0)