diff options
| author | Brian Anderson <[email protected]> | 2011-03-31 23:11:26 -0400 |
|---|---|---|
| committer | Brian Anderson <[email protected]> | 2011-03-31 23:15:11 -0400 |
| commit | f16e7242d2433378a0530d31427fad4ddd36c69f (patch) | |
| tree | 688abbbfa6505f59cd81134fe48aa4e9e30d172b /src | |
| parent | Only use allocas to hold expression results for boxed types (diff) | |
| download | rust-f16e7242d2433378a0530d31427fad4ddd36c69f.tar.xz rust-f16e7242d2433378a0530d31427fad4ddd36c69f.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/comp/middle/trans.rs | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index f6d59b92..c04e9748 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -5384,21 +5384,29 @@ fn trans_block(@block_ctxt cx, &ast.block b) -> result { if (is_terminated(bcx)) { ret r; } else { - // The value resulting from the block gets copied into an - // alloca created in an enclosing scope and it's refcount - // bumped so that it can escape this block. This means that - // it will definitely live until the end of the enclosing - // scope, even if nobody uses it, which may be something of - // a surprise. - auto r_ty = ty.expr_ty(e); if (ty.type_is_boxed(r_ty)) { - - // Create an alloca up in the llallocas block to hold the - // expression result. + // The value resulting from the block gets copied into an + // alloca created in an outer scope and it's refcount + // bumped so that it can escape this block. This means + // that it will definitely live until the end of the + // enclosing scope, even if nobody uses it, which may be + // something of a surprise. + + // It's possible we never hit this block, so the alloca + // must be initialized to null, then when the potential + // value finally goes out of scope the drop glue will see + // that it was never used and ignore it. + + // NB: Here we're building and initalizing the alloca in + // the alloca context, not this block's context. auto res_alloca = alloc_ty(bcx, r_ty); - bcx = res_alloca.bcx; + auto alloca_ty = type_of(bcx.fcx.ccx, r_ty); + auto builder = new_builder(bcx.fcx.llallocas); + builder.Store(C_null(alloca_ty), res_alloca.val); + + // Now we're working in our own block context again auto res_copy = copy_ty(bcx, INIT, res_alloca.val, r.val, r_ty); bcx = res_copy.bcx; |