Skip to content

Commit 3264431

Browse files
committed
trans: When coercing to Box<Trait> or Box<[T]>, leave datum in its original L-/R-value state.
This fixes a subtle issue where temporaries were being allocated (but not necessarily initialized) to the (parent) terminating scope of a match expression; in particular, the code to zero out the temporary emitted by `datum.store_to` is only attached to the particular match-arm for that temporary, but when going down other arms of the match expression, the temporary may falsely appear to have been initialized, depending on what the stack held at that location, and thus may have its destructor erroneously run at the end of the terminating scope. Test cases to appear in a follow-up commit. Fix rust-lang#20055
1 parent e365e4c commit 3264431

File tree

1 file changed

+16
-7
lines changed

1 file changed

+16
-7
lines changed

src/librustc_trans/trans/expr.rs

+16-7
Original file line numberDiff line numberDiff line change
@@ -420,9 +420,15 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
420420
let tcx = bcx.tcx();
421421

422422
let datum_ty = datum.ty;
423-
// Arrange cleanup
424-
let lval = unpack_datum!(bcx,
425-
datum.to_lvalue_datum(bcx, "unsize_unique_vec", expr.id));
423+
424+
debug!("unsize_unique_vec expr.id={} datum_ty={} len={}",
425+
expr.id, datum_ty.repr(tcx), len);
426+
427+
// We do not arrange cleanup ourselves; if we already are an
428+
// L-value, then cleanup will have already been scheduled (and
429+
// the `datum.store_to` call below will emit code to zero the
430+
// drop flag when moving out of the L-value). If we are an R-value,
431+
// then we do not need to schedule cleanup.
426432

427433
let ll_len = C_uint(bcx.ccx(), len);
428434
let unit_ty = ty::sequence_element_type(tcx, ty::type_content(datum_ty));
@@ -433,7 +439,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
433439
let base = PointerCast(bcx,
434440
base,
435441
type_of::type_of(bcx.ccx(), datum_ty).ptr_to());
436-
bcx = lval.store_to(bcx, base);
442+
bcx = datum.store_to(bcx, base);
437443

438444
Store(bcx, ll_len, get_len(bcx, scratch.val));
439445
DatumBlock::new(bcx, scratch.to_expr_datum())
@@ -455,13 +461,16 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
455461
};
456462
let result_ty = ty::mk_uniq(tcx, ty::unsize_ty(tcx, unboxed_ty, k, expr.span));
457463

458-
let lval = unpack_datum!(bcx,
459-
datum.to_lvalue_datum(bcx, "unsize_unique_expr", expr.id));
464+
// We do not arrange cleanup ourselves; if we already are an
465+
// L-value, then cleanup will have already been scheduled (and
466+
// the `datum.store_to` call below will emit code to zero the
467+
// drop flag when moving out of the L-value). If we are an R-value,
468+
// then we do not need to schedule cleanup.
460469

461470
let scratch = rvalue_scratch_datum(bcx, result_ty, "__uniq_fat_ptr");
462471
let llbox_ty = type_of::type_of(bcx.ccx(), datum_ty);
463472
let base = PointerCast(bcx, get_dataptr(bcx, scratch.val), llbox_ty.ptr_to());
464-
bcx = lval.store_to(bcx, base);
473+
bcx = datum.store_to(bcx, base);
465474

466475
let info = unsized_info(bcx, k, expr.id, unboxed_ty, |t| ty::mk_uniq(tcx, t));
467476
Store(bcx, info, get_len(bcx, scratch.val));

0 commit comments

Comments
 (0)