about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2011-06-29 12:16:07 -0700
committerPatrick Walton <pcwalton@mimiga.net>2011-06-29 12:16:07 -0700
commitb18cefdfd70cd4fb7308940d9b63956bac987ef1 (patch)
tree4533dffa6c0d769c2faa79f679284daa11c2fa7e
parenta2ce532337442e1e9a4efb3d10945dacf359ea20 (diff)
downloadrust-b18cefdfd70cd4fb7308940d9b63956bac987ef1.tar.gz
rust-b18cefdfd70cd4fb7308940d9b63956bac987ef1.zip
rustc: Fix a leak that resulted from copying a structural interior type containing interior vectors. Add a test case.
-rw-r--r--src/comp/middle/trans.rs17
-rw-r--r--src/test/run-pass/generic-ivec-leak.rs10
2 files changed, 15 insertions, 12 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 35906ffc9c0..7bed2cb168a 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -1931,9 +1931,7 @@ fn make_copy_glue(&@block_ctxt cx, ValueRef v, &ty::t t) {
         bcx = incr_refcnt_of_boxed(cx, cx.build.Load(v)).bcx;
     } else if (ty::type_is_structural(cx.fcx.lcx.ccx.tcx, t)) {
         bcx = iter_structural_ty(cx, v, t, bind copy_ty(_, _, _)).bcx;
-        if (ty::type_owns_heap_mem(cx.fcx.lcx.ccx.tcx, t)) {
-            bcx = duplicate_heap_parts(bcx, v, t).bcx;
-        }
+        bcx = duplicate_heap_parts_if_necessary(bcx, v, t).bcx;
     } else { bcx = cx; }
     bcx.build.RetVoid();
 }
@@ -3132,8 +3130,9 @@ fn memmove_ty(&@block_ctxt cx, ValueRef dst, ValueRef src, &ty::t t) ->
     } else { ret rslt(cx, cx.build.Store(cx.build.Load(src), dst)); }
 }
 
-// Duplicates the heap-owned memory owned by a value of the given type.
-fn duplicate_heap_parts(&@block_ctxt cx, ValueRef vptr, ty::t typ) -> result {
+// Duplicates any heap-owned memory owned by a value of the given type.
+fn duplicate_heap_parts_if_necessary(&@block_ctxt cx, ValueRef vptr,
+                                     ty::t typ) -> result {
     alt (ty::struct(cx.fcx.lcx.ccx.tcx, typ)) {
       case (ty::ty_ivec(?tm)) {
         ret ivec::duplicate_heap_part(cx, vptr, tm.ty);
@@ -3142,13 +3141,7 @@ fn duplicate_heap_parts(&@block_ctxt cx, ValueRef vptr, ty::t typ) -> result {
         ret ivec::duplicate_heap_part(cx, vptr,
             ty::mk_mach(cx.fcx.lcx.ccx.tcx, common::ty_u8));
       }
-      case (_) {    // TODO: guard
-        if (ty::type_is_structural(cx.fcx.lcx.ccx.tcx, typ)) {
-            ret iter_structural_ty(cx, vptr, typ, duplicate_heap_parts);
-        }
-
-        ret rslt(cx, C_nil());
-      }
+      case (_) { ret rslt(cx, C_nil()); }
     }
 }
 
diff --git a/src/test/run-pass/generic-ivec-leak.rs b/src/test/run-pass/generic-ivec-leak.rs
new file mode 100644
index 00000000000..4bf776c4ba1
--- /dev/null
+++ b/src/test/run-pass/generic-ivec-leak.rs
@@ -0,0 +1,10 @@
+// xfail-stage0
+
+tag wrapper[T] {
+    wrapped(T);
+}
+
+fn main() {
+    auto w = wrapped(~[ 1, 2, 3, 4, 5 ]);
+}
+