From 0fe880bdb788032100b9cd1633770b56393784f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Tue, 17 Feb 2015 10:43:27 +0100 Subject: [PATCH] Use the right array type in trans_slice_vec In trans_slice_vec we currently use arrayalloca, which gives us a pointer to the element type with enough memory allocated for the requested number of elements. This works, but everywhere else we use the [n x T] type for fixed size arrays and so we have to bitcast the pointer here. Let's directly use the proper type for the allocation and remove some code duplication along the way. --- src/librustc_trans/trans/base.rs | 13 ------------- src/librustc_trans/trans/tvec.rs | 28 +++++++++++----------------- 2 files changed, 11 insertions(+), 30 deletions(-) diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 7f7b5cd80066..971d73aa899b 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -1219,19 +1219,6 @@ pub fn alloca_zeroed<'blk, 'tcx>(cx: Block<'blk, 'tcx>, ty: Ty<'tcx>, p } -pub fn arrayalloca(cx: Block, ty: Type, v: ValueRef) -> ValueRef { - let _icx = push_ctxt("arrayalloca"); - if cx.unreachable.get() { - unsafe { - return llvm::LLVMGetUndef(ty.to_ref()); - } - } - debuginfo::clear_source_location(cx.fcx); - let p = ArrayAlloca(cx, ty, v); - call_lifetime_start(cx, p); - p -} - // Creates the alloca slot which holds the pointer to the slot for the final return value pub fn make_return_slot_pointer<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>, output_type: Ty<'tcx>) -> ValueRef { diff --git a/src/librustc_trans/trans/tvec.rs b/src/librustc_trans/trans/tvec.rs index 8f10865ae32b..bf94a2e23daf 100644 --- a/src/librustc_trans/trans/tvec.rs +++ b/src/librustc_trans/trans/tvec.rs @@ -171,33 +171,27 @@ pub fn trans_slice_vec<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let vt = vec_types_from_expr(bcx, content_expr); let count = elements_required(bcx, content_expr); debug!(" vt={}, count={}", vt.to_string(ccx), count); - let llcount = C_uint(ccx, count); let fixed_ty = ty::mk_vec(bcx.tcx(), vt.unit_ty, Some(count)); - let llfixed_ty = type_of::type_of(bcx.ccx(), fixed_ty).ptr_to(); + let llfixed_ty = type_of::type_of(bcx.ccx(), fixed_ty); - let llfixed = if count == 0 { - // Just create a zero-sized alloca to preserve - // the non-null invariant of the inner slice ptr - let llfixed = base::arrayalloca(bcx, vt.llunit_ty, llcount); - BitCast(bcx, llfixed, llfixed_ty) - } else { - // Make a fixed-length backing array and allocate it on the stack. - let llfixed = base::arrayalloca(bcx, vt.llunit_ty, llcount); + // Always create an alloca even if zero-sized, to preserve + // the non-null invariant of the inner slice ptr + let llfixed = base::alloca(bcx, llfixed_ty, ""); + if count > 0 { // Arrange for the backing array to be cleaned up. - let llfixed_casted = BitCast(bcx, llfixed, llfixed_ty); let cleanup_scope = cleanup::temporary_scope(bcx.tcx(), content_expr.id); - fcx.schedule_lifetime_end(cleanup_scope, llfixed_casted); - fcx.schedule_drop_mem(cleanup_scope, llfixed_casted, fixed_ty); + fcx.schedule_lifetime_end(cleanup_scope, llfixed); + fcx.schedule_drop_mem(cleanup_scope, llfixed, fixed_ty); // Generate the content into the backing array. - bcx = write_content(bcx, &vt, slice_expr, - content_expr, SaveIn(llfixed)); - - llfixed_casted + // llfixed has type *[T x N], but we want the type *T, + // so use GEP to convert + bcx = write_content(bcx, &vt, slice_expr, content_expr, + SaveIn(GEPi(bcx, llfixed, &[0, 0]))); }; immediate_rvalue_bcx(bcx, llfixed, vec_ty).to_expr_datumblock()