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
|
||||
if bcx.unreachable { ret bcx; }
|
||||
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)));
|
||||
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)));
|
||||
}*/
|
||||
}// */
|
||||
invoker(bcx, llfn, llargs, normal_bcx.llbb, get_landing_pad(bcx));
|
||||
ret normal_bcx;
|
||||
}
|
||||
|
||||
@@ -115,9 +115,12 @@ fn trans_monomorphized_callee(bcx: block, callee_id: ast::node_id,
|
||||
let ty_substs = impl_substs +
|
||||
vec::tailn(node_substs, node_substs.len() - n_m_tps);
|
||||
let {bcx, val} = trans_self_arg(bcx, base);
|
||||
{env: self_env(val, node_id_type(bcx, base.id), none)
|
||||
with lval_static_fn_inner(bcx, mth_id, callee_id, ty_substs,
|
||||
some(sub_origins))}
|
||||
let lval = lval_static_fn_inner(bcx, mth_id, callee_id, ty_substs,
|
||||
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) {
|
||||
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,
|
||||
ty::mk_fn(tcx, im.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 {
|
||||
let m_id = method_with_name(ccx, impl_id, im.ident);
|
||||
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}) {
|
||||
let tcx = fcx.ccx.tcx;
|
||||
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 n_tys == 0u || n_tys != method_n_tps {
|
||||
if n_tys != 0u {
|
||||
@@ -3335,15 +3335,16 @@ mod vtable {
|
||||
}
|
||||
|
||||
fn lookup_vtables(fcx: @fn_ctxt, isc: resolve::iscopes, sp: span,
|
||||
bounds: @[ty::param_bounds], tys: [ty::t])
|
||||
-> vtable_res {
|
||||
bounds: @[ty::param_bounds], tys: [ty::t],
|
||||
allow_unsafe: bool) -> vtable_res {
|
||||
let tcx = fcx.ccx.tcx, result = [], i = 0u;
|
||||
for ty in tys {
|
||||
for bound in *bounds[i] {
|
||||
alt bound {
|
||||
ty::bound_iface(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,
|
||||
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 (iface_id, iface_tps) = alt check ty::get(iface_ty).struct {
|
||||
ty::ty_iface(did, tps) { (did, tps) }
|
||||
@@ -3378,6 +3380,20 @@ mod vtable {
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
_ {
|
||||
@@ -3410,8 +3426,8 @@ mod vtable {
|
||||
im.did);
|
||||
let params = vec::map(vars, {|t|
|
||||
fixup_ty(fcx, sp, t)});
|
||||
let subres = lookup_vtables(fcx, isc, sp,
|
||||
im_bs, params);
|
||||
let subres = lookup_vtables(
|
||||
fcx, isc, sp, im_bs, params, false);
|
||||
found = some(vtable_static(im.did, params,
|
||||
subres));
|
||||
}
|
||||
@@ -3469,7 +3485,7 @@ mod vtable {
|
||||
if has_iface_bounds(*item_ty.bounds) {
|
||||
let impls = cx.impl_map.get(ex.id);
|
||||
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 iscs = cx.impl_map.get(ex.id);
|
||||
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(_, _) {
|
||||
let impls = cx.impl_map.get(ex.id);
|
||||
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]);
|
||||
}
|
||||
_ {}
|
||||
|
||||
Reference in New Issue
Block a user