From b773f8d22b7e132aa9dd59090b939bc612ac8d83 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 30 Jun 2011 19:08:57 -0700 Subject: [PATCH] rustc: Duplicate heap data of interior vectors when passing them by value --- src/comp/middle/trans.rs | 16 +++++++++++++++- src/test/run-pass/ivec-pass-by-value.rs | 5 +++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 src/test/run-pass/ivec-pass-by-value.rs diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index b20074a77167..6da9a5785104 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 000000000000..0badde5ceb33 --- /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 ]); } +