Fix auto_ref()
for fat pointers
`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
This commit is contained in:
parent
38201501df
commit
575f690b39
@ -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>,
|
||||
|
Loading…
Reference in New Issue
Block a user