Skip to content

Commit 1f4117f

Browse files
committed
auto merge of #17110 : thestinger/rust/dst, r=cmr
The pointer in the slice must not be null, because enum representations make that assumption. The `exchange_malloc` function returns a non-null sentinel for the zero size case, and it must not be passed to the `exchange_free` lang item. Since the length is always equal to the true capacity, a branch on the length is enough for most types. Slices of zero size types are statically special cased to never attempt deallocation. This is the same implementation as `Vec<T>`. Closes #14395
2 parents 7ea660e + 9639caf commit 1f4117f

File tree

4 files changed

+24
-37
lines changed

4 files changed

+24
-37
lines changed

src/liballoc/heap.rs

-6
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
// FIXME: #13996: mark the `allocate` and `reallocate` return value as `noalias`
1313
// and `nonnull`
1414

15-
use core::ptr::RawPtr;
1615
#[cfg(not(test))] use core::raw;
1716
#[cfg(stage0, not(test))] use util;
1817

@@ -70,11 +69,6 @@ pub unsafe fn reallocate_inplace(ptr: *mut u8, size: uint, align: uint,
7069
/// the value returned by `usable_size` for the requested size.
7170
#[inline]
7271
pub unsafe fn deallocate(ptr: *mut u8, size: uint, align: uint) {
73-
// FIXME(14395) This is only required for DST ~[T], it should be removed once
74-
// we fix that representation to not use null pointers.
75-
if ptr.is_null() {
76-
return;
77-
}
7872
imp::deallocate(ptr, size, align)
7973
}
8074

src/librustc/middle/trans/expr.rs

+5-23
Original file line numberDiff line numberDiff line change
@@ -412,29 +412,11 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
412412
let vec_ty = ty::mk_uniq(tcx, ty::mk_vec(tcx, unit_ty, None));
413413
let scratch = rvalue_scratch_datum(bcx, vec_ty, "__unsize_unique");
414414

415-
if len == 0 {
416-
Store(bcx,
417-
C_null(type_of::type_of(bcx.ccx(), unit_ty).ptr_to()),
418-
get_dataptr(bcx, scratch.val));
419-
} else {
420-
// Box<[(), ..n]> will not allocate, but ~[()] expects an
421-
// allocation of n bytes, so we must allocate here (yuck).
422-
let llty = type_of::type_of(bcx.ccx(), unit_ty);
423-
if llsize_of_alloc(bcx.ccx(), llty) == 0 {
424-
let ptr_unit_ty = type_of::type_of(bcx.ccx(), unit_ty).ptr_to();
425-
let align = C_uint(bcx.ccx(), 8);
426-
let alloc_result = malloc_raw_dyn(bcx, ptr_unit_ty, vec_ty, ll_len, align);
427-
bcx = alloc_result.bcx;
428-
let base = get_dataptr(bcx, scratch.val);
429-
Store(bcx, alloc_result.val, base);
430-
} else {
431-
let base = get_dataptr(bcx, scratch.val);
432-
let base = PointerCast(bcx,
433-
base,
434-
type_of::type_of(bcx.ccx(), datum_ty).ptr_to());
435-
bcx = lval.store_to(bcx, base);
436-
}
437-
}
415+
let base = get_dataptr(bcx, scratch.val);
416+
let base = PointerCast(bcx,
417+
base,
418+
type_of::type_of(bcx.ccx(), datum_ty).ptr_to());
419+
bcx = lval.store_to(bcx, base);
438420

439421
Store(bcx, ll_len, get_len(bcx, scratch.val));
440422
DatumBlock::new(bcx, scratch.to_expr_datum())

src/librustc/middle/trans/tvec.rs

+13-8
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,19 @@ pub fn make_drop_glue_unboxed<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
7272
};
7373

7474
if should_deallocate {
75-
let not_null = IsNotNull(bcx, dataptr);
76-
with_cond(bcx, not_null, |bcx| {
77-
let llty = type_of::type_of(ccx, unit_ty);
78-
let llsize = machine::llsize_of(ccx, llty);
79-
let llalign = C_uint(ccx, machine::llalign_of_min(ccx, llty) as uint);
80-
let size = Mul(bcx, llsize, get_len(bcx, vptr));
81-
glue::trans_exchange_free_dyn(bcx, dataptr, size, llalign)
82-
})
75+
let llty = type_of::type_of(ccx, unit_ty);
76+
let unit_size = llsize_of_alloc(ccx, llty);
77+
if unit_size != 0 {
78+
let len = get_len(bcx, vptr);
79+
let not_empty = ICmp(bcx, llvm::IntNE, len, C_uint(ccx, 0));
80+
with_cond(bcx, not_empty, |bcx| {
81+
let llalign = C_uint(ccx, machine::llalign_of_min(ccx, llty) as uint);
82+
let size = Mul(bcx, C_uint(ccx, unit_size as uint), len);
83+
glue::trans_exchange_free_dyn(bcx, dataptr, size, llalign)
84+
})
85+
} else {
86+
bcx
87+
}
8388
} else {
8489
bcx
8590
}

src/test/run-pass/empty-allocation-non-null.rs

+6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
pub fn main() {
1212
assert!(Some(box() ()).is_some());
1313

14+
let xs: Box<[()]> = box [];
15+
assert!(Some(xs).is_some());
16+
1417
struct Foo;
1518
assert!(Some(box Foo).is_some());
19+
20+
let ys: Box<[Foo]> = box [];
21+
assert!(Some(ys).is_some());
1622
}

0 commit comments

Comments
 (0)