Forbid boxed ifaces with self types or generic methods in bounded params
They are a soundness hole. Closes #1994
This commit is contained in:
@@ -2668,12 +2668,12 @@ fn invoke_(bcx: block, llfn: ValueRef, llargs: [ValueRef],
|
|||||||
// cleanups to run
|
// cleanups to run
|
||||||
if bcx.unreachable { ret bcx; }
|
if bcx.unreachable { ret bcx; }
|
||||||
let normal_bcx = sub_block(bcx, "normal return");
|
let normal_bcx = sub_block(bcx, "normal return");
|
||||||
/*std::io::println("fn: " + lib::llvm::type_to_str(bcx.ccx().tn,
|
/*io::println("fn: " + lib::llvm::type_to_str(bcx.ccx().tn,
|
||||||
val_ty(llfn)));
|
val_ty(llfn)));
|
||||||
for a in llargs {
|
for a in llargs {
|
||||||
std::io::println(" a: " + lib::llvm::type_to_str(bcx.ccx().tn,
|
io::println(" a: " + lib::llvm::type_to_str(bcx.ccx().tn,
|
||||||
val_ty(a)));
|
val_ty(a)));
|
||||||
}*/
|
}// */
|
||||||
invoker(bcx, llfn, llargs, normal_bcx.llbb, get_landing_pad(bcx));
|
invoker(bcx, llfn, llargs, normal_bcx.llbb, get_landing_pad(bcx));
|
||||||
ret normal_bcx;
|
ret normal_bcx;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,9 +115,12 @@ fn trans_monomorphized_callee(bcx: block, callee_id: ast::node_id,
|
|||||||
let ty_substs = impl_substs +
|
let ty_substs = impl_substs +
|
||||||
vec::tailn(node_substs, node_substs.len() - n_m_tps);
|
vec::tailn(node_substs, node_substs.len() - n_m_tps);
|
||||||
let {bcx, val} = trans_self_arg(bcx, base);
|
let {bcx, val} = trans_self_arg(bcx, base);
|
||||||
{env: self_env(val, node_id_type(bcx, base.id), none)
|
let lval = lval_static_fn_inner(bcx, mth_id, callee_id, ty_substs,
|
||||||
with lval_static_fn_inner(bcx, mth_id, callee_id, ty_substs,
|
some(sub_origins));
|
||||||
some(sub_origins))}
|
{env: self_env(val, node_id_type(bcx, base.id), none),
|
||||||
|
val: PointerCast(bcx, lval.val, T_ptr(type_of_fn_from_ty(
|
||||||
|
ccx, node_id_type(bcx, callee_id))))
|
||||||
|
with lval}
|
||||||
}
|
}
|
||||||
typeck::vtable_iface(iid, tps) {
|
typeck::vtable_iface(iid, tps) {
|
||||||
trans_iface_callee(bcx, base, callee_id, n_method)
|
trans_iface_callee(bcx, base, callee_id, n_method)
|
||||||
@@ -236,7 +239,7 @@ fn make_impl_vtable(ccx: @crate_ctxt, impl_id: ast::def_id, substs: [ty::t],
|
|||||||
let fty = ty::substitute_type_params(tcx, substs,
|
let fty = ty::substitute_type_params(tcx, substs,
|
||||||
ty::mk_fn(tcx, im.fty));
|
ty::mk_fn(tcx, im.fty));
|
||||||
if (*im.tps).len() > 0u || ty::type_has_vars(fty) {
|
if (*im.tps).len() > 0u || ty::type_has_vars(fty) {
|
||||||
C_null(type_of_fn_from_ty(ccx, fty))
|
C_null(T_ptr(T_nil()))
|
||||||
} else {
|
} else {
|
||||||
let m_id = method_with_name(ccx, impl_id, im.ident);
|
let m_id = method_with_name(ccx, impl_id, im.ident);
|
||||||
if has_tps {
|
if has_tps {
|
||||||
|
|||||||
@@ -1782,7 +1782,7 @@ fn lookup_method(fcx: @fn_ctxt, expr: @ast::expr, node_id: ast::node_id,
|
|||||||
some({method_ty: fty, n_tps: method_n_tps, substs, origin, self_sub}) {
|
some({method_ty: fty, n_tps: method_n_tps, substs, origin, self_sub}) {
|
||||||
let tcx = fcx.ccx.tcx;
|
let tcx = fcx.ccx.tcx;
|
||||||
let substs = substs, n_tps = vec::len(substs), n_tys = vec::len(tps);
|
let substs = substs, n_tps = vec::len(substs), n_tys = vec::len(tps);
|
||||||
let has_self = ty::type_has_params(fty);
|
let has_self = ty::type_has_vars(fty);
|
||||||
if method_n_tps + n_tps > 0u {
|
if method_n_tps + n_tps > 0u {
|
||||||
if n_tys == 0u || n_tys != method_n_tps {
|
if n_tys == 0u || n_tys != method_n_tps {
|
||||||
if n_tys != 0u {
|
if n_tys != 0u {
|
||||||
@@ -3335,15 +3335,16 @@ mod vtable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn lookup_vtables(fcx: @fn_ctxt, isc: resolve::iscopes, sp: span,
|
fn lookup_vtables(fcx: @fn_ctxt, isc: resolve::iscopes, sp: span,
|
||||||
bounds: @[ty::param_bounds], tys: [ty::t])
|
bounds: @[ty::param_bounds], tys: [ty::t],
|
||||||
-> vtable_res {
|
allow_unsafe: bool) -> vtable_res {
|
||||||
let tcx = fcx.ccx.tcx, result = [], i = 0u;
|
let tcx = fcx.ccx.tcx, result = [], i = 0u;
|
||||||
for ty in tys {
|
for ty in tys {
|
||||||
for bound in *bounds[i] {
|
for bound in *bounds[i] {
|
||||||
alt bound {
|
alt bound {
|
||||||
ty::bound_iface(i_ty) {
|
ty::bound_iface(i_ty) {
|
||||||
let i_ty = ty::substitute_type_params(tcx, tys, i_ty);
|
let i_ty = ty::substitute_type_params(tcx, tys, i_ty);
|
||||||
result += [lookup_vtable(fcx, isc, sp, ty, i_ty)];
|
result += [lookup_vtable(fcx, isc, sp, ty, i_ty,
|
||||||
|
allow_unsafe)];
|
||||||
}
|
}
|
||||||
_ {}
|
_ {}
|
||||||
}
|
}
|
||||||
@@ -3354,7 +3355,8 @@ mod vtable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn lookup_vtable(fcx: @fn_ctxt, isc: resolve::iscopes, sp: span,
|
fn lookup_vtable(fcx: @fn_ctxt, isc: resolve::iscopes, sp: span,
|
||||||
ty: ty::t, iface_ty: ty::t) -> vtable_origin {
|
ty: ty::t, iface_ty: ty::t, allow_unsafe: bool)
|
||||||
|
-> vtable_origin {
|
||||||
let tcx = fcx.ccx.tcx;
|
let tcx = fcx.ccx.tcx;
|
||||||
let (iface_id, iface_tps) = alt check ty::get(iface_ty).struct {
|
let (iface_id, iface_tps) = alt check ty::get(iface_ty).struct {
|
||||||
ty::ty_iface(did, tps) { (did, tps) }
|
ty::ty_iface(did, tps) { (did, tps) }
|
||||||
@@ -3378,6 +3380,20 @@ mod vtable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::ty_iface(did, tps) if iface_id == did {
|
ty::ty_iface(did, tps) if iface_id == did {
|
||||||
|
if !allow_unsafe {
|
||||||
|
for m in *ty::iface_methods(tcx, did) {
|
||||||
|
if ty::type_has_vars(ty::mk_fn(tcx, m.fty)) {
|
||||||
|
tcx.sess.span_err(
|
||||||
|
sp, "a boxed iface with self types may not be \
|
||||||
|
passed as a bounded type");
|
||||||
|
} else if (*m.tps).len() > 0u {
|
||||||
|
tcx.sess.span_err(
|
||||||
|
sp, "a boxed iface with generic methods may not \
|
||||||
|
be passed as a bounded type");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
ret vtable_iface(did, tps);
|
ret vtable_iface(did, tps);
|
||||||
}
|
}
|
||||||
_ {
|
_ {
|
||||||
@@ -3410,8 +3426,8 @@ mod vtable {
|
|||||||
im.did);
|
im.did);
|
||||||
let params = vec::map(vars, {|t|
|
let params = vec::map(vars, {|t|
|
||||||
fixup_ty(fcx, sp, t)});
|
fixup_ty(fcx, sp, t)});
|
||||||
let subres = lookup_vtables(fcx, isc, sp,
|
let subres = lookup_vtables(
|
||||||
im_bs, params);
|
fcx, isc, sp, im_bs, params, false);
|
||||||
found = some(vtable_static(im.did, params,
|
found = some(vtable_static(im.did, params,
|
||||||
subres));
|
subres));
|
||||||
}
|
}
|
||||||
@@ -3469,7 +3485,7 @@ mod vtable {
|
|||||||
if has_iface_bounds(*item_ty.bounds) {
|
if has_iface_bounds(*item_ty.bounds) {
|
||||||
let impls = cx.impl_map.get(ex.id);
|
let impls = cx.impl_map.get(ex.id);
|
||||||
cx.vtable_map.insert(ex.id, lookup_vtables(
|
cx.vtable_map.insert(ex.id, lookup_vtables(
|
||||||
fcx, impls, ex.span, item_ty.bounds, ts));
|
fcx, impls, ex.span, item_ty.bounds, ts, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ {}
|
_ {}
|
||||||
@@ -3490,7 +3506,7 @@ mod vtable {
|
|||||||
let ts = ty::node_id_to_type_params(cx.tcx, callee_id);
|
let ts = ty::node_id_to_type_params(cx.tcx, callee_id);
|
||||||
let iscs = cx.impl_map.get(ex.id);
|
let iscs = cx.impl_map.get(ex.id);
|
||||||
cx.vtable_map.insert(callee_id, lookup_vtables(
|
cx.vtable_map.insert(callee_id, lookup_vtables(
|
||||||
fcx, iscs, ex.span, bounds, ts));
|
fcx, iscs, ex.span, bounds, ts, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ {}
|
_ {}
|
||||||
@@ -3502,7 +3518,8 @@ mod vtable {
|
|||||||
ty::ty_iface(_, _) {
|
ty::ty_iface(_, _) {
|
||||||
let impls = cx.impl_map.get(ex.id);
|
let impls = cx.impl_map.get(ex.id);
|
||||||
let vtable = lookup_vtable(fcx, impls, ex.span,
|
let vtable = lookup_vtable(fcx, impls, ex.span,
|
||||||
expr_ty(cx.tcx, src), target_ty);
|
expr_ty(cx.tcx, src), target_ty,
|
||||||
|
true);
|
||||||
cx.vtable_map.insert(ex.id, @[vtable]);
|
cx.vtable_map.insert(ex.id, @[vtable]);
|
||||||
}
|
}
|
||||||
_ {}
|
_ {}
|
||||||
|
|||||||
Reference in New Issue
Block a user