@@ -1026,6 +1026,18 @@ fn find_scope_cx(@block_ctxt cx) -> @block_ctxt {
1026
1026
}
1027
1027
}
1028
1028
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
+
1029
1041
fn umax ( @block_ctxt cx , ValueRef a, ValueRef b) -> ValueRef {
1030
1042
auto cond = cx. build . ICmp ( lib. llvm . LLVMIntULT , a, b) ;
1031
1043
ret cx. build . Select ( cond, b, a) ;
@@ -5368,8 +5380,55 @@ fn trans_block(@block_ctxt cx, &ast.block b) -> result {
5368
5380
case ( some[ @ast. expr] ( ?e) ) {
5369
5381
r = trans_expr( bcx, e) ;
5370
5382
bcx = r. bcx;
5383
+
5371
5384
if ( is_terminated( bcx) ) {
5372
5385
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
+ }
5373
5432
}
5374
5433
}
5375
5434
case ( none[ @ast. expr] ) {
0 commit comments