aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBrian Anderson <[email protected]>2011-03-31 23:11:26 -0400
committerBrian Anderson <[email protected]>2011-03-31 23:15:11 -0400
commitf16e7242d2433378a0530d31427fad4ddd36c69f (patch)
tree688abbbfa6505f59cd81134fe48aa4e9e30d172b /src
parentOnly use allocas to hold expression results for boxed types (diff)
downloadrust-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.rs30
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;