Skip to content

Commit

Permalink
Fix auto_ref() for fat pointers
Browse files Browse the repository at this point in the history
`auto_ref()` currently returns an Rvalue datum for the ref'd value,
which is fine for thin pointers, but for fat pointers this means that
once the pointer is moved out of that datum, its memory will be marked
as dead. And because there is not necessarily an intermediate temporary
involved we can end up marking memory as dead that is actually still
used.

As I don't want to break the micro-optimization for thin pointers by
always returning an Lvalue datum, I decided to only do so for fat
pointers.

Fix #30478
  • Loading branch information
dotdash committed Dec 27, 2015
1 parent 3820150 commit 575f690
Showing 1 changed file with 11 additions and 7 deletions.
18 changes: 11 additions & 7 deletions src/librustc_trans/trans/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2187,15 +2187,19 @@ fn auto_ref<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let referent_ty = lv_datum.ty;
let ptr_ty = bcx.tcx().mk_imm_ref(bcx.tcx().mk_region(ty::ReStatic), referent_ty);

// Construct the resulting datum. The right datum to return here would be an Lvalue datum,
// because there is cleanup scheduled and the datum doesn't own the data, but for thin pointers
// we microoptimize it to be an Rvalue datum to avoid the extra alloca and level of
// indirection and for thin pointers, this has no ill effects.
let kind = if type_is_sized(bcx.tcx(), referent_ty) {
RvalueExpr(Rvalue::new(ByValue))
} else {
LvalueExpr(lv_datum.kind)
};

// Get the pointer.
let llref = lv_datum.to_llref();

// Construct the resulting datum, using what was the "by ref"
// ValueRef of type `referent_ty` to be the "by value" ValueRef
// of type `&referent_ty`.
// Pointers to DST types are non-immediate, and therefore still use ByRef.
let kind = if type_is_sized(bcx.tcx(), referent_ty) { ByValue } else { ByRef };
DatumBlock::new(bcx, Datum::new(llref, ptr_ty, RvalueExpr(Rvalue::new(kind))))
DatumBlock::new(bcx, Datum::new(llref, ptr_ty, kind))
}

fn deref_multiple<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
Expand Down

0 comments on commit 575f690

Please sign in to comment.