From 415d7e8ae9065d76855f5685939c362dd6be2544 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Fri, 29 Aug 2014 18:37:45 +1200 Subject: [PATCH] Don't double free embedded, unsized slices Thanks to @eddyb for finding the bug. Closes #16826 (I hope) --- src/librustc/middle/trans/glue.rs | 6 +++--- src/librustc/middle/trans/tvec.rs | 18 ++++++++++++------ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 24c939dc3be8b..51cd9a115cd7c 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 94ca520c533f9..a6ba758d5f810 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 + } }) }