about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-08-29 13:56:29 +0000
committerbors <bors@rust-lang.org>2014-08-29 13:56:29 +0000
commit602592675ce86aeca465c4ac748cee2bff291443 (patch)
tree0e2e1f2654731a9c53b864211820d98f7ed4c853
parentf6a7ab40e84d80990ceaf7755e30a575367e5c32 (diff)
parent415d7e8ae9065d76855f5685939c362dd6be2544 (diff)
downloadrust-602592675ce86aeca465c4ac748cee2bff291443.tar.gz
rust-602592675ce86aeca465c4ac748cee2bff291443.zip
auto merge of #16838 : nick29581/rust/dst-bug-4, r=pnkfelix,nikomatsakis
Don't double free embedded, unsized slices.

Merge/rebase error from DST. Thanks to @eddyb for finding.

Closes #16826 (I hope)

r?
-rw-r--r--src/librustc/middle/trans/glue.rs6
-rw-r--r--src/librustc/middle/trans/tvec.rs18
2 files changed, 15 insertions, 9 deletions
diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs
index 24c939dc3be..51cd9a115cd 100644
--- a/src/librustc/middle/trans/glue.rs
+++ b/src/librustc/middle/trans/glue.rs
@@ -403,11 +403,11 @@ fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'
         ty::ty_uniq(content_ty) => {
             match ty::get(content_ty).sty {
                 ty::ty_vec(ty, None) => {
-                    tvec::make_drop_glue_unboxed(bcx, v0, ty)
+                    tvec::make_drop_glue_unboxed(bcx, v0, ty, true)
                 }
                 ty::ty_str => {
                     let unit_ty = ty::sequence_element_type(bcx.tcx(), t);
-                    tvec::make_drop_glue_unboxed(bcx, v0, unit_ty)
+                    tvec::make_drop_glue_unboxed(bcx, v0, unit_ty, true)
                 }
                 ty::ty_trait(..) => {
                     let lluniquevalue = GEPi(bcx, v0, [0, abi::trt_field_box]);
@@ -507,7 +507,7 @@ fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'
                  None);
             bcx
         }
-        ty::ty_vec(ty, None) => tvec::make_drop_glue_unboxed(bcx, v0, ty),
+        ty::ty_vec(ty, None) => tvec::make_drop_glue_unboxed(bcx, v0, ty, false),
         _ => {
             assert!(ty::type_is_sized(bcx.tcx(), t));
             if ty::type_needs_drop(bcx.tcx(), t) &&
diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs
index 94ca520c533..a6ba758d5f8 100644
--- a/src/librustc/middle/trans/tvec.rs
+++ b/src/librustc/middle/trans/tvec.rs
@@ -54,25 +54,31 @@ pub fn pointer_add_byte(bcx: &Block, ptr: ValueRef, bytes: ValueRef) -> ValueRef
 pub fn make_drop_glue_unboxed<'a>(
                               bcx: &'a Block<'a>,
                               vptr: ValueRef,
-                              unit_ty: ty::t)
+                              unit_ty: ty::t,
+                              should_deallocate: bool)
                               -> &'a Block<'a> {
     let not_null = IsNotNull(bcx, vptr);
     with_cond(bcx, not_null, |bcx| {
         let tcx = bcx.tcx();
         let _icx = push_ctxt("tvec::make_drop_glue_unboxed");
 
-        let len = get_len(bcx, vptr);
         let dataptr = get_dataptr(bcx, vptr);
         let bcx = if ty::type_needs_drop(tcx, unit_ty) {
+            let len = get_len(bcx, vptr);
             iter_vec_raw(bcx, dataptr, unit_ty, len, glue::drop_ty)
         } else {
             bcx
         };
 
-        let not_null = IsNotNull(bcx, dataptr);
-        with_cond(bcx, not_null, |bcx| {
-            glue::trans_exchange_free(bcx, dataptr, 0, 8)
-        })
+        if should_deallocate {
+            let not_null = IsNotNull(bcx, dataptr);
+            with_cond(bcx, not_null, |bcx| {
+                // FIXME: #13994: the old `Box<[T]>` will not support sized deallocation
+                glue::trans_exchange_free(bcx, dataptr, 0, 8)
+            })
+        } else {
+            bcx
+        }
     })
 }