rustc: When revoking a cleanup of a unique pointer, zero it out so that the GC won't try to visit it
This commit is contained in:
parent
7a0c9759fe
commit
fb9ab95a15
@ -2179,18 +2179,15 @@ fn move_val(cx: @block_ctxt, action: copy_action, dst: ValueRef,
|
||||
if src.is_mem { ret zero_alloca(cx, src.res.val, t).bcx; }
|
||||
|
||||
// If we're here, it must be a temporary.
|
||||
revoke_clean(cx, src_val);
|
||||
ret cx;
|
||||
ret revoke_clean(cx, src_val, t);
|
||||
} else if ty::type_is_unique(tcx, t) ||
|
||||
type_is_structural_or_param(tcx, t) {
|
||||
if action == DROP_EXISTING { cx = drop_ty(cx, dst, t); }
|
||||
cx = memmove_ty(cx, dst, src_val, t).bcx;
|
||||
if src.is_mem {
|
||||
ret zero_alloca(cx, src_val, t).bcx;
|
||||
} else { // Temporary value
|
||||
revoke_clean(cx, src_val);
|
||||
ret cx;
|
||||
}
|
||||
if src.is_mem { ret zero_alloca(cx, src_val, t).bcx; }
|
||||
|
||||
// If we're here, it must be a temporary.
|
||||
ret revoke_clean(cx, src_val, t);
|
||||
}
|
||||
bcx_ccx(cx).sess.bug("unexpected type in trans::move_val: " +
|
||||
ty_to_str(tcx, t));
|
||||
@ -3620,7 +3617,8 @@ fn trans_bind_1(cx: &@block_ctxt, f: &@ast::expr, f_res: &lval_result,
|
||||
|
||||
fn trans_arg_expr(cx: &@block_ctxt, arg: &ty::arg, lldestty0: TypeRef,
|
||||
to_zero: &mutable [{v: ValueRef, t: ty::t}],
|
||||
to_revoke: &mutable [ValueRef], e: &@ast::expr) -> result {
|
||||
to_revoke: &mutable [{v: ValueRef, t: ty::t}],
|
||||
e: &@ast::expr) -> result {
|
||||
let ccx = bcx_ccx(cx);
|
||||
let e_ty = ty::expr_ty(ccx.tcx, e);
|
||||
let is_bot = ty::type_is_bot(ccx.tcx, e_ty);
|
||||
@ -3672,7 +3670,9 @@ fn trans_arg_expr(cx: &@block_ctxt, arg: &ty::arg, lldestty0: TypeRef,
|
||||
// Use actual ty, not declared ty -- anything else doesn't make
|
||||
// sense if declared ty is a ty param
|
||||
to_zero += [{v: lv.res.val, t: e_ty}];
|
||||
} else { to_revoke += [lv.res.val]; }
|
||||
} else {
|
||||
to_revoke += [{v: lv.res.val, t: e_ty}];
|
||||
}
|
||||
}
|
||||
ret rslt(bcx, val);
|
||||
}
|
||||
@ -3691,7 +3691,7 @@ fn trans_args(cx: &@block_ctxt, llenv: ValueRef,
|
||||
args: [ValueRef],
|
||||
retslot: ValueRef,
|
||||
to_zero: [{v: ValueRef, t: ty::t}],
|
||||
to_revoke: [ValueRef]} {
|
||||
to_revoke: [{v: ValueRef, t: ty::t}]} {
|
||||
|
||||
let args: [ty::arg] = ty::ty_fn_args(bcx_tcx(cx), fn_ty);
|
||||
let llargs: [ValueRef] = [];
|
||||
@ -3869,9 +3869,11 @@ fn trans_call(in_cx: &@block_ctxt, f: &@ast::expr,
|
||||
|
||||
// Forget about anything we moved out.
|
||||
for {v: v, t: t}: {v: ValueRef, t: ty::t} in args_res.to_zero {
|
||||
zero_alloca(bcx, v, t)
|
||||
bcx = zero_alloca(bcx, v, t).bcx;
|
||||
}
|
||||
for {v: v, t: t} in args_res.to_revoke {
|
||||
bcx = revoke_clean(bcx, v, t);
|
||||
}
|
||||
for v: ValueRef in args_res.to_revoke { revoke_clean(bcx, v) }
|
||||
bcx = trans_block_cleanups(bcx, cx);
|
||||
let next_cx = new_sub_block_ctxt(in_cx, "next");
|
||||
Br(bcx, next_cx.llbb);
|
||||
|
@ -314,7 +314,13 @@ fn add_clean_temp(cx: &@block_ctxt, val: ValueRef, ty: ty::t) {
|
||||
// to a system where we can also cancel the cleanup on local variables, but
|
||||
// this will be more involved. For now, we simply zero out the local, and the
|
||||
// drop glue checks whether it is zero.
|
||||
fn revoke_clean(cx: &@block_ctxt, val: ValueRef) {
|
||||
fn revoke_clean(cx: &@block_ctxt, val: ValueRef, t: ty::t) -> @block_ctxt {
|
||||
if ty::type_is_unique(bcx_tcx(cx), t) {
|
||||
// Just zero out the allocation. This ensures that the GC won't try to
|
||||
// traverse dangling pointers.
|
||||
ret trans::zero_alloca(cx, val, t).bcx;
|
||||
}
|
||||
|
||||
let sc_cx = find_scope_cx(cx);
|
||||
let found = -1;
|
||||
let i = 0;
|
||||
@ -329,12 +335,14 @@ fn revoke_clean(cx: &@block_ctxt, val: ValueRef) {
|
||||
}
|
||||
// The value does not have a cleanup associated with it. Might be a
|
||||
// constant or some immediate value.
|
||||
if found == -1 { ret; }
|
||||
if found == -1 { ret cx; }
|
||||
// We found the cleanup and remove it
|
||||
sc_cx.cleanups =
|
||||
std::vec::slice(sc_cx.cleanups, 0u, found as uint) +
|
||||
std::vec::slice(sc_cx.cleanups, (found as uint) + 1u,
|
||||
std::vec::len(sc_cx.cleanups));
|
||||
|
||||
ret cx;
|
||||
}
|
||||
|
||||
fn get_res_dtor(ccx: &@crate_ctxt, sp: &span, did: &ast::def_id,
|
||||
|
Loading…
x
Reference in New Issue
Block a user