@@ -4656,7 +4656,10 @@ fn trans_bind_1(cx: &@block_ctxt, f: &@ast::expr, f_res: &lval_result,
4656
4656
ret rslt( bcx, pair_v) ;
4657
4657
}
4658
4658
4659
- fn trans_arg_expr ( cx : & @block_ctxt , arg : & ty:: arg , lldestty0 : TypeRef ,
4659
+ fn trans_arg_expr ( cx : & @block_ctxt , arg : & ty:: arg ,
4660
+ lldestty0 : TypeRef ,
4661
+ to_zero : & mutable[ { v: ValueRef , t : ty:: t } ] ,
4662
+ to_revoke : & mutable[ ValueRef ] ,
4660
4663
e : & @ast:: expr ) -> result {
4661
4664
let ccx = bcx_ccx ( cx) ;
4662
4665
let e_ty = ty:: expr_ty ( ccx. tcx , e) ;
@@ -4711,6 +4714,15 @@ fn trans_arg_expr(cx: &@block_ctxt, arg: &ty::arg, lldestty0: TypeRef,
4711
4714
// we are now passing it as an arg, so need to load it.
4712
4715
val = bcx. build . Load ( val) ;
4713
4716
}
4717
+
4718
+ // Collect arg for later if it happens to be one we've moving out.
4719
+ if arg. mode == ty:: mo_move {
4720
+ if lv. is_mem {
4721
+ to_zero += ~[ { v: lv. res . val , t: arg. ty } ] ;
4722
+ } else {
4723
+ to_revoke += ~[ lv. res . val ] ;
4724
+ }
4725
+ }
4714
4726
ret rslt( bcx, val) ;
4715
4727
}
4716
4728
@@ -4724,10 +4736,18 @@ fn trans_arg_expr(cx: &@block_ctxt, arg: &ty::arg, lldestty0: TypeRef,
4724
4736
fn trans_args ( cx : & @block_ctxt , llenv : ValueRef ,
4725
4737
gen : & option:: t [ generic_info ] , lliterbody : & option:: t [ ValueRef ] ,
4726
4738
es : & [ @ast:: expr ] , fn_ty : & ty:: t ) ->
4727
- { bcx : @block_ctxt , args : [ ValueRef ] , retslot : ValueRef } {
4739
+ { bcx : @block_ctxt ,
4740
+ args : [ ValueRef ] ,
4741
+ retslot : ValueRef ,
4742
+ to_zero : [ { v : ValueRef , t : ty:: t } ] ,
4743
+ to_revoke : [ ValueRef ] } {
4744
+
4728
4745
let args: [ ty:: arg ] = ty:: ty_fn_args ( bcx_tcx ( cx) , fn_ty) ;
4729
4746
let llargs: [ ValueRef ] = ~[ ] ;
4730
4747
let lltydescs: [ ValueRef ] = ~[ ] ;
4748
+ let to_zero = ~[ ] ;
4749
+ let to_revoke = ~[ ] ;
4750
+
4731
4751
let bcx: @block_ctxt = cx;
4732
4752
// Arg 0: Output pointer.
4733
4753
@@ -4736,9 +4756,9 @@ fn trans_args(cx: &@block_ctxt, llenv: ValueRef,
4736
4756
if bcx. build . is_terminated ( ) {
4737
4757
// This means an earlier arg was divergent.
4738
4758
// So this arg can't be evaluated.
4739
- ret { bcx : bcx, args : ~[ ] , retslot : C_nil ( ) } ;
4759
+ ret { bcx : bcx, args : ~[ ] , retslot : C_nil ( ) ,
4760
+ to_zero : to_zero, to_revoke : to_revoke} ;
4740
4761
}
4741
-
4742
4762
let retty = ty:: ty_fn_ret ( bcx_tcx ( cx) , fn_ty) ;
4743
4763
let llretslot_res = alloc_ty ( bcx, retty) ;
4744
4764
bcx = llretslot_res. bcx ;
@@ -4787,12 +4807,14 @@ fn trans_args(cx: &@block_ctxt, llenv: ValueRef,
4787
4807
// So this arg can't be evaluated.
4788
4808
break ;
4789
4809
}
4790
- let r = trans_arg_expr ( bcx, args. ( i) , arg_tys. ( i) , e) ;
4810
+ let r = trans_arg_expr ( bcx, args. ( i) , arg_tys. ( i) ,
4811
+ to_zero, to_revoke, e) ;
4791
4812
bcx = r. bcx ;
4792
4813
llargs += ~[ r. val ] ;
4793
4814
i += 1 u;
4794
4815
}
4795
- ret { bcx : bcx, args : llargs, retslot : llretslot} ;
4816
+ ret { bcx : bcx, args : llargs, retslot : llretslot,
4817
+ to_zero : to_zero, to_revoke : to_revoke} ;
4796
4818
}
4797
4819
4798
4820
fn trans_call ( cx : & @block_ctxt , f : & @ast:: expr ,
@@ -4875,6 +4897,14 @@ fn trans_call(cx: &@block_ctxt, f: &@ast::expr,
4875
4897
// we should ignore llretslot.
4876
4898
}
4877
4899
}
4900
+
4901
+ // Forget about anything we moved out.
4902
+ for { v, t} : { v: ValueRef , t: ty:: t} in args_res. to_zero {
4903
+ zero_alloca ( bcx, v, t)
4904
+ }
4905
+ for v: ValueRef in args_res. to_revoke {
4906
+ revoke_clean ( bcx, v)
4907
+ }
4878
4908
}
4879
4909
ret rslt( bcx, retval) ;
4880
4910
}
@@ -5493,7 +5523,9 @@ fn trans_put(cx: &@block_ctxt, e: &option::t[@ast::expr]) -> result {
5493
5523
let e_ty = ty:: expr_ty ( bcx_tcx ( cx) , x) ;
5494
5524
let arg = { mode: ty:: mo_alias ( false ) , ty: e_ty} ;
5495
5525
let arg_tys = type_of_explicit_args ( bcx_ccx ( cx) , x. span , ~[ arg] ) ;
5496
- let r = trans_arg_expr ( bcx, arg, arg_tys. ( 0 ) , x) ;
5526
+ let z = ~[ ] ;
5527
+ let k = ~[ ] ;
5528
+ let r = trans_arg_expr ( bcx, arg, arg_tys. ( 0 ) , z, k, x) ;
5497
5529
bcx = r. bcx ;
5498
5530
llargs += ~[ r. val ] ;
5499
5531
}
@@ -6035,13 +6067,13 @@ fn add_cleanups_for_args(bcx: &@block_ctxt, args: &[ast::arg],
6035
6067
arg_tys : & [ ty:: arg ] ) {
6036
6068
let arg_n: uint = 0 u;
6037
6069
for aarg: ast:: arg in args {
6038
- if aarg. mode == ast:: val {
6070
+ if aarg. mode == ast:: val || aarg . mode == ast :: move {
6039
6071
let argval;
6040
6072
alt bcx. fcx . llargs . find ( aarg. id ) {
6041
6073
some ( x) { argval = x; }
6042
6074
_ {
6043
6075
bcx_ccx( bcx) . sess . span_fatal
6044
- ( aarg. ty . span , "unbound arg ID in copy_args_to_allocas " ) ;
6076
+ ( aarg. ty . span , "unbound arg ID in add_cleanups_for_args " ) ;
6045
6077
}
6046
6078
}
6047
6079
add_clean ( bcx, argval, arg_tys. ( arg_n) . ty ) ;
0 commit comments