@@ -1395,13 +1395,20 @@ impure fn trans_args(@block_ctxt cx, &vec[@ast.expr] es, @typeck.ty fn_ty)
1395
1395
}
1396
1396
1397
1397
impure fn trans_call( @block_ctxt cx, @ast. expr f,
1398
- vec[ @ast. expr] args) -> result {
1398
+ vec[ @ast. expr] args, & ast . ann ann ) -> result {
1399
1399
auto f_res = trans_lval( cx, f) ;
1400
1400
check ( ! f_res. _1) ;
1401
1401
auto fn_ty = typeck. expr_ty( f) ;
1402
+ auto ret_ty = typeck. ann_to_type( ann) ;
1402
1403
auto args_res = trans_args( f_res. _0. bcx, args, fn_ty) ;
1403
- ret res( args_res. _0,
1404
- args_res. _0. build. FastCall ( f_res. _0. val, args_res. _1) ) ;
1404
+ auto retval = args_res. _0. build. FastCall ( f_res. _0. val, args_res. _1) ;
1405
+
1406
+ // Retval doesn't correspond to anything really tangible in the frame, but
1407
+ // it's a ref all the same, so we put a note here to drop it when we're
1408
+ // done in this scope.
1409
+ find_scope_cx( cx) . cleanups += clean( bind drop_ty( _, retval, ret_ty) ) ;
1410
+
1411
+ ret res( args_res. _0, retval) ;
1405
1412
}
1406
1413
1407
1414
impure fn trans_tup( @block_ctxt cx, vec[ ast. elt] elts,
@@ -1502,8 +1509,8 @@ impure fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
1502
1509
ret copy_ty( rhs_res. bcx, false , lhs_res. _0. val, v, t) ;
1503
1510
}
1504
1511
1505
- case ( ast. expr_call( ?f, ?args, _ ) ) {
1506
- ret trans_call( cx, f, args) ;
1512
+ case ( ast. expr_call( ?f, ?args, ?ann ) ) {
1513
+ ret trans_call( cx, f, args, ann ) ;
1507
1514
}
1508
1515
1509
1516
case ( ast. expr_cast( ?e, _, ?ann) ) {
@@ -1590,7 +1597,21 @@ impure fn trans_ret(@block_ctxt cx, &option.t[@ast.expr] e) -> result {
1590
1597
auto r = res( cx, C_nil ( ) ) ;
1591
1598
alt ( e) {
1592
1599
case ( some[ @ast. expr] ( ?x) ) {
1600
+ auto t = typeck. expr_ty( x) ;
1593
1601
r = trans_expr( cx, x) ;
1602
+ if ( typeck. type_is_structural( t) ) {
1603
+ // We usually treat structurals by-pointer; in particular,
1604
+ // trans_expr will have given us a structure pointer. But in
1605
+ // this case we're about to return. LLVM wants a first-class
1606
+ // value here (which makes sense; the frame is going away!)
1607
+ r. val = r. bcx. build. Load ( r. val) ;
1608
+ }
1609
+ if ( typeck. type_is_boxed( t) ) {
1610
+ // A return is an implicit ++ on the refcount on any boxed
1611
+ // value, as it is being newly referenced as the anonymous
1612
+ // 'return value' from the function, in the caller frame.
1613
+ r. bcx = incr_refcnt( r. bcx, r. val) . bcx;
1614
+ }
1594
1615
}
1595
1616
case ( _) { /* fall through */ }
1596
1617
}
@@ -1611,14 +1632,7 @@ impure fn trans_ret(@block_ctxt cx, &option.t[@ast.expr] e) -> result {
1611
1632
}
1612
1633
1613
1634
alt ( e) {
1614
- case ( some[ @ast. expr] ( ?e) ) {
1615
- if ( typeck. type_is_structural( typeck. expr_ty( e) ) ) {
1616
- // We usually treat structurals by-pointer; in particular,
1617
- // trans_expr will have given us a structure pointer. But in
1618
- // this case we're about to return. LLVM wants a first-class
1619
- // value here (which makes sense; the frame is going away!)
1620
- r. val = r. bcx. build. Load ( r. val) ;
1621
- }
1635
+ case ( some[ @ast. expr] ( _) ) {
1622
1636
r. val = r. bcx. build. Ret ( r. val) ;
1623
1637
ret r;
1624
1638
}
0 commit comments