Dereference classes with dtors only on a field access

A class with a dtor has a different representation (a pair of a bit field
and a pointer to the class itself), and previously, the trans code
was selecting out the second field on any reference to a variable whose
type was a class with a dtor. This turned out to be wrong in the case where
a closure captures a variable with such a type. Changed the code to only
insert the field selection on a class field access.
This commit is contained in:
Tim Chevalier 2012-06-05 15:06:47 -07:00
parent 7daf986aec
commit 8972588583

View File

@ -2448,19 +2448,7 @@ fn trans_local_var(cx: block, def: ast::def) -> local_var_result {
}
ast::def_self(sid) {
let slf = alt copy cx.fcx.llself {
some(s) {
alt option::map(ty::ty_to_def_id(s.t)) {|did|
ty::ty_dtor(cx.tcx(), did)} {
some(some(_)) {
/* self is a class with a dtor, which means we
have to select out the object itself
(If any other code does the same thing, that's
a bug */
GEPi(cx, cast_self(cx, s), [0u, 1u])
}
_ { cast_self(cx, s) }
}
}
some(s) { cast_self(cx, s) }
none { cx.sess().bug("trans_local_var: reference to self \
out of context"); }
};
@ -2535,9 +2523,13 @@ fn trans_rec_field(bcx: block, base: @ast::expr,
fn trans_rec_field_inner(bcx: block, val: ValueRef, ty: ty::t,
field: ast::ident, sp: span) -> lval_result {
let mut deref = false;
let fields = alt ty::get(ty).struct {
ty::ty_rec(fs) { fs }
ty::ty_class(did, substs) {
if option::is_some(ty::ty_dtor(bcx.tcx(), did)) {
deref = true;
}
ty::class_items_as_fields(bcx.tcx(), did, substs)
}
// Constraint?
@ -2545,7 +2537,15 @@ fn trans_rec_field_inner(bcx: block, val: ValueRef, ty: ty::t,
base expr has non-record type"); }
};
let ix = field_idx_strict(bcx.tcx(), sp, field, fields);
let val = GEPi(bcx, val, [0u, ix]);
/* self is a class with a dtor, which means we
have to select out the object itself
(If any other code does the same thing, that's
a bug */
let val = if deref {
GEPi(bcx, GEPi(bcx, val, [0u, 1u]), [0u, ix])
}
else { GEPi(bcx, val, [0u, ix]) };
ret {bcx: bcx, val: val, kind: owned};
}