rustc: Run block cleanups on else if blocks

With the scheme used to translate 'else if' currently the if expression is
translated in a new (else) scope context. If that if expression wants to
result in a value that requires refcounting then it will need to drop the
refcount in the cleanups of the else block.
This commit is contained in:
Brian Anderson 2011-05-17 20:35:37 -04:00
parent e840a37f33
commit a98ea4f3ef
2 changed files with 26 additions and 2 deletions

View file

@ -3706,8 +3706,15 @@ fn trans_if(&@block_ctxt cx, &@ast::expr cond,
alt (els) {
case (some[@ast::expr](?elexpr)) {
alt (elexpr.node) {
case (ast::expr_if(_, _, _, _)) {
else_res = trans_expr(else_cx, elexpr);
case (ast::expr_if(?cond, ?thn, ?els, _)) {
else_res = trans_if(else_cx, cond, thn, els);
// The if expression may need to use the else context to
// drop the refcount of its result so we need to run the
// cleanups
auto bcx = else_res.bcx;
bcx = trans_block_cleanups(bcx,
find_scope_cx(bcx));
else_res = res(bcx, else_res.val);
}
case (ast::expr_block(?blk, _)) {
// Calling trans_block directly instead of trans_expr

View file

@ -0,0 +1,17 @@
// xfail-stage0
// Make sure we drop the refs of the temporaries needed to return the
// values from the else if branch
fn main() {
let vec[uint] y = [10u];
auto x = if (false) {
y
} else if (true) {
y
} else {
y
};
assert y.(0) == 10u;
}