Don't double free embedded, unsized slices
Thanks to @eddyb for finding the bug. Closes #16826 (I hope)
This commit is contained in:
parent
dee8423531
commit
415d7e8ae9
|
@ -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) => {
|
ty::ty_uniq(content_ty) => {
|
||||||
match ty::get(content_ty).sty {
|
match ty::get(content_ty).sty {
|
||||||
ty::ty_vec(ty, None) => {
|
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 => {
|
ty::ty_str => {
|
||||||
let unit_ty = ty::sequence_element_type(bcx.tcx(), t);
|
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(..) => {
|
ty::ty_trait(..) => {
|
||||||
let lluniquevalue = GEPi(bcx, v0, [0, abi::trt_field_box]);
|
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);
|
None);
|
||||||
bcx
|
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));
|
assert!(ty::type_is_sized(bcx.tcx(), t));
|
||||||
if ty::type_needs_drop(bcx.tcx(), t) &&
|
if ty::type_needs_drop(bcx.tcx(), t) &&
|
||||||
|
|
|
@ -54,25 +54,31 @@ pub fn pointer_add_byte(bcx: &Block, ptr: ValueRef, bytes: ValueRef) -> ValueRef
|
||||||
pub fn make_drop_glue_unboxed<'a>(
|
pub fn make_drop_glue_unboxed<'a>(
|
||||||
bcx: &'a Block<'a>,
|
bcx: &'a Block<'a>,
|
||||||
vptr: ValueRef,
|
vptr: ValueRef,
|
||||||
unit_ty: ty::t)
|
unit_ty: ty::t,
|
||||||
|
should_deallocate: bool)
|
||||||
-> &'a Block<'a> {
|
-> &'a Block<'a> {
|
||||||
let not_null = IsNotNull(bcx, vptr);
|
let not_null = IsNotNull(bcx, vptr);
|
||||||
with_cond(bcx, not_null, |bcx| {
|
with_cond(bcx, not_null, |bcx| {
|
||||||
let tcx = bcx.tcx();
|
let tcx = bcx.tcx();
|
||||||
let _icx = push_ctxt("tvec::make_drop_glue_unboxed");
|
let _icx = push_ctxt("tvec::make_drop_glue_unboxed");
|
||||||
|
|
||||||
let len = get_len(bcx, vptr);
|
|
||||||
let dataptr = get_dataptr(bcx, vptr);
|
let dataptr = get_dataptr(bcx, vptr);
|
||||||
let bcx = if ty::type_needs_drop(tcx, unit_ty) {
|
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)
|
iter_vec_raw(bcx, dataptr, unit_ty, len, glue::drop_ty)
|
||||||
} else {
|
} else {
|
||||||
bcx
|
bcx
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if should_deallocate {
|
||||||
let not_null = IsNotNull(bcx, dataptr);
|
let not_null = IsNotNull(bcx, dataptr);
|
||||||
with_cond(bcx, not_null, |bcx| {
|
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)
|
glue::trans_exchange_free(bcx, dataptr, 0, 8)
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
bcx
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue