Skip to content

Commit f16e724

Browse files
committed
Initialize the alloca used to retrieve boxed block results to null.
This allows blocks to be used in conditional constructs where the block may not ever execute: the drop glue will notice that it was never used and ignore it. Also, beef up the comments.
1 parent 524e803 commit f16e724

File tree

1 file changed

+19
-11
lines changed

1 file changed

+19
-11
lines changed

src/comp/middle/trans.rs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5384,21 +5384,29 @@ fn trans_block(@block_ctxt cx, &ast.block b) -> result {
53845384
if (is_terminated(bcx)) {
53855385
ret r;
53865386
} 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-
53945387
auto r_ty = ty.expr_ty(e);
53955388

53965389
if (ty.type_is_boxed(r_ty)) {
5397-
5398-
// Create an alloca up in the llallocas block to hold the
5399-
// expression result.
5390+
// The value resulting from the block gets copied into an
5391+
// alloca created in an outer scope and it's refcount
5392+
// bumped so that it can escape this block. This means
5393+
// that it will definitely live until the end of the
5394+
// enclosing scope, even if nobody uses it, which may be
5395+
// something of a surprise.
5396+
5397+
// It's possible we never hit this block, so the alloca
5398+
// must be initialized to null, then when the potential
5399+
// value finally goes out of scope the drop glue will see
5400+
// that it was never used and ignore it.
5401+
5402+
// NB: Here we're building and initalizing the alloca in
5403+
// the alloca context, not this block's context.
54005404
auto res_alloca = alloc_ty(bcx, r_ty);
5401-
bcx = res_alloca.bcx;
5405+
auto alloca_ty = type_of(bcx.fcx.ccx, r_ty);
5406+
auto builder = new_builder(bcx.fcx.llallocas);
5407+
builder.Store(C_null(alloca_ty), res_alloca.val);
5408+
5409+
// Now we're working in our own block context again
54025410
auto res_copy = copy_ty(bcx, INIT,
54035411
res_alloca.val, r.val, r_ty);
54045412
bcx = res_copy.bcx;

0 commit comments

Comments
 (0)