Skip to content

Commit 9fb0867

Browse files
committed
---
yaml --- r: 4511 b: refs/heads/master c: a5997f2 h: refs/heads/master i: 4509: b8783d2 4507: 41bc3aa 4503: 48c6097 4495: 0d68fe0 4479: b9b9568 v: v3
1 parent 2050577 commit 9fb0867

File tree

3 files changed

+54
-10
lines changed

3 files changed

+54
-10
lines changed

[refs]

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 5adaa6f9562479fc9e2b85f00eb6ee73c42c80e1
2+
refs/heads/master: a5997f2eb21abdc083e0faa3adbfc44116e1014f

trunk/src/comp/middle/trans.rs

+41-9
Original file line numberDiff line numberDiff line change
@@ -4656,7 +4656,10 @@ fn trans_bind_1(cx: &@block_ctxt, f: &@ast::expr, f_res: &lval_result,
46564656
ret rslt(bcx, pair_v);
46574657
}
46584658

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],
46604663
e: &@ast::expr) -> result {
46614664
let ccx = bcx_ccx(cx);
46624665
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,
47114714
// we are now passing it as an arg, so need to load it.
47124715
val = bcx.build.Load(val);
47134716
}
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+
}
47144726
ret rslt(bcx, val);
47154727
}
47164728

@@ -4724,10 +4736,18 @@ fn trans_arg_expr(cx: &@block_ctxt, arg: &ty::arg, lldestty0: TypeRef,
47244736
fn trans_args(cx: &@block_ctxt, llenv: ValueRef,
47254737
gen: &option::t[generic_info], lliterbody: &option::t[ValueRef],
47264738
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+
47284745
let args: [ty::arg] = ty::ty_fn_args(bcx_tcx(cx), fn_ty);
47294746
let llargs: [ValueRef] = ~[];
47304747
let lltydescs: [ValueRef] = ~[];
4748+
let to_zero = ~[];
4749+
let to_revoke = ~[];
4750+
47314751
let bcx: @block_ctxt = cx;
47324752
// Arg 0: Output pointer.
47334753

@@ -4736,9 +4756,9 @@ fn trans_args(cx: &@block_ctxt, llenv: ValueRef,
47364756
if bcx.build.is_terminated() {
47374757
// This means an earlier arg was divergent.
47384758
// 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};
47404761
}
4741-
47424762
let retty = ty::ty_fn_ret(bcx_tcx(cx), fn_ty);
47434763
let llretslot_res = alloc_ty(bcx, retty);
47444764
bcx = llretslot_res.bcx;
@@ -4787,12 +4807,14 @@ fn trans_args(cx: &@block_ctxt, llenv: ValueRef,
47874807
// So this arg can't be evaluated.
47884808
break;
47894809
}
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);
47914812
bcx = r.bcx;
47924813
llargs += ~[r.val];
47934814
i += 1u;
47944815
}
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};
47964818
}
47974819

47984820
fn trans_call(cx: &@block_ctxt, f: &@ast::expr,
@@ -4875,6 +4897,14 @@ fn trans_call(cx: &@block_ctxt, f: &@ast::expr,
48754897
// we should ignore llretslot.
48764898
}
48774899
}
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+
}
48784908
}
48794909
ret rslt(bcx, retval);
48804910
}
@@ -5493,7 +5523,9 @@ fn trans_put(cx: &@block_ctxt, e: &option::t[@ast::expr]) -> result {
54935523
let e_ty = ty::expr_ty(bcx_tcx(cx), x);
54945524
let arg = {mode: ty::mo_alias(false), ty: e_ty};
54955525
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);
54975529
bcx = r.bcx;
54985530
llargs += ~[r.val];
54995531
}
@@ -6035,13 +6067,13 @@ fn add_cleanups_for_args(bcx: &@block_ctxt, args: &[ast::arg],
60356067
arg_tys: &[ty::arg]) {
60366068
let arg_n: uint = 0u;
60376069
for aarg: ast::arg in args {
6038-
if aarg.mode == ast::val {
6070+
if aarg.mode == ast::val || aarg.mode == ast::move {
60396071
let argval;
60406072
alt bcx.fcx.llargs.find(aarg.id) {
60416073
some(x) { argval = x; }
60426074
_ {
60436075
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");
60456077
}
60466078
}
60476079
add_clean(bcx, argval, arg_tys.(arg_n).ty);

trunk/src/test/run-pass/move-arg-2.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
fn test(foo: -@[int]) {
2+
assert (foo.(0) == 10);
3+
}
4+
5+
fn main() {
6+
let x = @~[10];
7+
// Test forgetting a local by move-in
8+
test(x);
9+
10+
// Test forgetting a temporary by move-in.
11+
test(@~[10]);
12+
}

0 commit comments

Comments
 (0)