diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2011-06-30 19:08:57 -0700 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2011-06-30 19:09:52 -0700 |
| commit | b773f8d22b7e132aa9dd59090b939bc612ac8d83 (patch) | |
| tree | 61048f9268298677eb3e142607dec60010861f4d /src | |
| parent | 0eb257e864a36a459110a1d27f6447a770d855a7 (diff) | |
| download | rust-b773f8d22b7e132aa9dd59090b939bc612ac8d83.tar.gz rust-b773f8d22b7e132aa9dd59090b939bc612ac8d83.zip | |
rustc: Duplicate heap data of interior vectors when passing them by value
Diffstat (limited to 'src')
| -rw-r--r-- | src/comp/middle/trans.rs | 16 | ||||
| -rw-r--r-- | src/test/run-pass/ivec-pass-by-value.rs | 5 |
2 files changed, 20 insertions, 1 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index b20074a7716..6da9a578510 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -5515,7 +5515,21 @@ fn trans_arg_expr(&@block_ctxt cx, &ty::arg arg, TypeRef lldestty0, val = do_spill(lv.res.bcx, lv.res.val); } } else { auto re = trans_expr(bcx, e); val = re.val; bcx = re.bcx; } - if (arg.mode == ty::mo_val) { bcx = copy_ty(bcx, val, e_ty).bcx; } + + // Make a copy here if the type is structural and we're passing by value. + if (arg.mode == ty::mo_val) { + if (ty::type_owns_heap_mem(cx.fcx.lcx.ccx.tcx, e_ty)) { + auto rslt = alloc_ty(bcx, e_ty); + bcx = rslt.bcx; + auto dst = rslt.val; + rslt = copy_val(bcx, INIT, dst, val, e_ty); + bcx = rslt.bcx; + val = dst; + } else { + bcx = copy_ty(bcx, val, e_ty).bcx; + } + } + if (ty::type_is_bot(cx.fcx.lcx.ccx.tcx, e_ty)) { // For values of type _|_, we generate an // "undef" value, as such a value should never diff --git a/src/test/run-pass/ivec-pass-by-value.rs b/src/test/run-pass/ivec-pass-by-value.rs new file mode 100644 index 00000000000..0badde5ceb3 --- /dev/null +++ b/src/test/run-pass/ivec-pass-by-value.rs @@ -0,0 +1,5 @@ +// xfail-stage0 + +fn f(int[] a) {} +fn main() { f(~[ 1, 2, 3, 4, 5 ]); } + |
