Skip to content

Commit 8640e67

Browse files
committed
Add a precondition to GEP_tup_like
1 parent 2b98ecc commit 8640e67

File tree

3 files changed

+73
-4
lines changed

3 files changed

+73
-4
lines changed

src/comp/middle/trans.rs

+49-4
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,8 @@ fn dynamic_size_of(cx: @block_ctxt, t: ty::t) -> result {
610610
}
611611

612612
fn dynamic_align_of(cx: @block_ctxt, t: ty::t) -> result {
613+
// FIXME: Typestate constraint that shows this alt is
614+
// exhaustive
613615
alt ty::struct(bcx_tcx(cx), t) {
614616
ty::ty_param(p, _) {
615617
let aptr = field_of_tydesc(cx, t, false, abi::tydesc_field_align);
@@ -668,9 +670,8 @@ fn bump_ptr(bcx: @block_ctxt, t: ty::t, base: ValueRef, sz: ValueRef) ->
668670
// ty::struct and knows what to do when it runs into a ty_param stuck in the
669671
// middle of the thing it's GEP'ing into. Much like size_of and align_of,
670672
// above.
671-
fn GEP_tup_like(cx: @block_ctxt, t: ty::t, base: ValueRef, ixs: [int]) ->
672-
result {
673-
assert (ty::type_is_tup_like(bcx_tcx(cx), t));
673+
fn GEP_tup_like(cx: @block_ctxt, t: ty::t, base: ValueRef, ixs: [int])
674+
: type_is_tup_like(cx, t) -> result {
674675
// It might be a static-known type. Handle this.
675676
if !ty::type_has_dynamic_size(bcx_tcx(cx), t) {
676677
ret rslt(cx, GEPi(cx, base, ixs));
@@ -785,6 +786,8 @@ fn GEP_tag(cx: @block_ctxt, llblobptr: ValueRef, tag_id: ast::def_id,
785786
} else { llunionptr = llblobptr; }
786787

787788
// Do the GEP_tup_like().
789+
// Silly check -- postcondition on mk_tup?
790+
check type_is_tup_like(cx, tup_ty);
788791
let rs = GEP_tup_like(cx, tup_ty, llunionptr, [0, ix as int]);
789792
// Cast the result to the appropriate type, if necessary.
790793

@@ -1403,12 +1406,15 @@ fn trans_res_drop(cx: @block_ctxt, rs: ValueRef, did: ast::def_id,
14031406
let drop_cx = new_sub_block_ctxt(cx, "drop res");
14041407
let next_cx = new_sub_block_ctxt(cx, "next");
14051408

1409+
// Silly check
1410+
check type_is_tup_like(cx, tup_ty);
14061411
let drop_flag = GEP_tup_like(cx, tup_ty, rs, [0, 0]);
14071412
cx = drop_flag.bcx;
14081413
let null_test = IsNull(cx, Load(cx, drop_flag.val));
14091414
CondBr(cx, null_test, next_cx.llbb, drop_cx.llbb);
14101415
cx = drop_cx;
14111416

1417+
check type_is_tup_like(cx, tup_ty);
14121418
let val = GEP_tup_like(cx, tup_ty, rs, [0, 1]);
14131419
cx = val.bcx;
14141420
// Find and call the actual destructor.
@@ -1641,10 +1647,15 @@ fn iter_structural_ty(cx: @block_ctxt, av: ValueRef, t: ty::t,
16411647
ret cx;
16421648
}
16431649

1650+
/*
1651+
Typestate constraint that shows the unimpl case doesn't happen?
1652+
*/
16441653
alt ty::struct(bcx_tcx(cx), t) {
16451654
ty::ty_rec(fields) {
16461655
let i: int = 0;
16471656
for fld: ty::field in fields {
1657+
// Silly check
1658+
check type_is_tup_like(cx, t);
16481659
let {bcx: bcx, val: llfld_a} = GEP_tup_like(cx, t, av, [0, i]);
16491660
cx = f(bcx, llfld_a, fld.mt.ty);
16501661
i += 1;
@@ -1653,6 +1664,8 @@ fn iter_structural_ty(cx: @block_ctxt, av: ValueRef, t: ty::t,
16531664
ty::ty_tup(args) {
16541665
let i = 0;
16551666
for arg in args {
1667+
// Silly check
1668+
check type_is_tup_like(cx, t);
16561669
let {bcx: bcx, val: llfld_a} = GEP_tup_like(cx, t, av, [0, i]);
16571670
cx = f(bcx, llfld_a, arg);
16581671
i += 1;
@@ -1663,6 +1676,8 @@ fn iter_structural_ty(cx: @block_ctxt, av: ValueRef, t: ty::t,
16631676
let inner1 = ty::substitute_type_params(tcx, tps, inner);
16641677
let inner_t_s = ty::substitute_type_params(tcx, tps, inner);
16651678
let tup_t = ty::mk_tup(tcx, [ty::mk_int(tcx), inner_t_s]);
1679+
// Silly check
1680+
check type_is_tup_like(cx, tup_t);
16661681
let {bcx: bcx, val: llfld_a} = GEP_tup_like(cx, tup_t, av, [0, 1]);
16671682
ret f(bcx, llfld_a, inner1);
16681683
}
@@ -2543,11 +2558,15 @@ fn build_environment(bcx: @block_ctxt, lltydescs: [ValueRef],
25432558

25442559
// Copy expr values into boxed bindings.
25452560
let i = 0u;
2561+
// Silly check
2562+
check type_is_tup_like(bcx, closure_ty);
25462563
let bindings =
25472564
GEP_tup_like(bcx, closure_ty, closure,
25482565
[0, abi::closure_elt_bindings]);
25492566
bcx = bindings.bcx;
25502567
for lv: lval_result in bound_vals {
2568+
// Also a silly check
2569+
check type_is_tup_like(bcx, bindings_ty);
25512570
let bound =
25522571
GEP_tup_like(bcx, bindings_ty, bindings.val, [0, i as int]);
25532572
bcx = bound.bcx;
@@ -2559,6 +2578,8 @@ fn build_environment(bcx: @block_ctxt, lltydescs: [ValueRef],
25592578

25602579
// If necessary, copy tydescs describing type parameters into the
25612580
// appropriate slot in the closure.
2581+
// Silly check as well
2582+
check type_is_tup_like(bcx, closure_ty);
25622583
let ty_params_slot =
25632584
GEP_tup_like(bcx, closure_ty, closure,
25642585
[0, abi::closure_elt_ty_params]);
@@ -2663,6 +2684,8 @@ fn load_environment(enclosing_cx: @block_ctxt, fcx: @fn_ctxt, envty: ty::t,
26632684
// If this is an aliasing closure/for-each body, we need to load
26642685
// the iterbody.
26652686
if !copying && !option::is_none(enclosing_cx.fcx.lliterbody) {
2687+
// Silly check
2688+
check type_is_tup_like(bcx, ty);
26662689
let iterbodyptr = GEP_tup_like(bcx, ty, llclosure, path + [0]);
26672690
fcx.lliterbody = some(Load(bcx, iterbodyptr.val));
26682691
bcx = iterbodyptr.bcx;
@@ -2671,6 +2694,8 @@ fn load_environment(enclosing_cx: @block_ctxt, fcx: @fn_ctxt, envty: ty::t,
26712694

26722695
// Load the actual upvars.
26732696
for upvar_def in *upvars {
2697+
// Silly check
2698+
check type_is_tup_like(bcx, ty);
26742699
let upvarptr = GEP_tup_like(bcx, ty, llclosure, path + [i as int]);
26752700
bcx = upvarptr.bcx;
26762701
let llupvarptr = upvarptr.val;
@@ -2984,7 +3009,10 @@ fn trans_field_inner(cx: @block_ctxt, sp: span, v: ValueRef, t0: ty::t,
29843009
alt ty::struct(bcx_tcx(cx), t) {
29853010
ty::ty_rec(fields) {
29863011
let ix: uint = ty::field_idx(bcx_ccx(cx).sess, sp, field, fields);
2987-
let v = GEP_tup_like(r.bcx, t, r.val, [0, ix as int]);
3012+
let r_bcx = r.bcx;
3013+
// Silly check
3014+
check type_is_tup_like(r_bcx, t);
3015+
let v = GEP_tup_like(r_bcx, t, r.val, [0, ix as int]);
29883016
ret lval_no_env(v.bcx, v.val, true);
29893017
}
29903018
ty::ty_obj(methods) {
@@ -3329,6 +3357,8 @@ fn trans_bind_thunk(cx: @local_ctxt, sp: span, incoming_fty: ty::t,
33293357
(fptr, C_null(T_opaque_closure_ptr(*bcx_ccx(bcx))), 0)
33303358
}
33313359
none. {
3360+
// Silly check
3361+
check type_is_tup_like(bcx, closure_ty);
33323362
let {bcx: cx, val: pair} =
33333363
GEP_tup_like(bcx, closure_ty, llclosure,
33343364
[0, abi::box_rc_field_body,
@@ -3368,6 +3398,8 @@ fn trans_bind_thunk(cx: @local_ctxt, sp: span, incoming_fty: ty::t,
33683398
// Copy in the type parameters.
33693399
let i: uint = 0u;
33703400
while i < ty_param_count {
3401+
// Silly check
3402+
check type_is_tup_like(copy_args_bcx, closure_ty);
33713403
let lltyparam_ptr =
33723404
GEP_tup_like(copy_args_bcx, closure_ty, llclosure,
33733405
[0, abi::box_rc_field_body,
@@ -3391,6 +3423,8 @@ fn trans_bind_thunk(cx: @local_ctxt, sp: span, incoming_fty: ty::t,
33913423
// Arg provided at binding time; thunk copies it from
33923424
// closure.
33933425
some(e) {
3426+
// Silly check
3427+
check type_is_tup_like(bcx, closure_ty);
33943428
let bound_arg =
33953429
GEP_tup_like(bcx, closure_ty, llclosure,
33963430
[0, abi::box_rc_field_body,
@@ -3914,6 +3948,8 @@ fn trans_tup(cx: @block_ctxt, elts: [@ast::expr], id: ast::node_id) ->
39143948
let e_ty = ty::expr_ty(cx.fcx.lcx.ccx.tcx, e);
39153949
let src = trans_lval(bcx, e);
39163950
bcx = src.bcx;
3951+
// FIXME: constraint on argument?
3952+
check type_is_tup_like(bcx, t);
39173953
let dst_res = GEP_tup_like(bcx, t, tup_val, [0, i]);
39183954
bcx = move_val_if_temp(dst_res.bcx, INIT, dst_res.val, src, e_ty);
39193955
i += 1;
@@ -3943,6 +3979,8 @@ fn trans_rec(cx: @block_ctxt, fields: [ast::field],
39433979
alt ty::struct(bcx_tcx(cx), t) { ty::ty_rec(flds) { ty_fields = flds; } }
39443980
for tf: ty::field in ty_fields {
39453981
let e_ty = tf.mt.ty;
3982+
// FIXME: constraint on argument?
3983+
check type_is_tup_like(bcx, t);
39463984
let dst_res = GEP_tup_like(bcx, t, rec_val, [0, i]);
39473985
bcx = dst_res.bcx;
39483986
let expr_provided = false;
@@ -3956,6 +3994,8 @@ fn trans_rec(cx: @block_ctxt, fields: [ast::field],
39563994
}
39573995
}
39583996
if !expr_provided {
3997+
// FIXME: constraint on argument?
3998+
check type_is_tup_like(bcx, t);
39593999
let src_res = GEP_tup_like(bcx, t, base_val, [0, i]);
39604000
src_res =
39614001
rslt(src_res.bcx, load_if_immediate(bcx, src_res.val, e_ty));
@@ -5100,6 +5140,8 @@ fn populate_fn_ctxt_from_llself(fcx: @fn_ctxt, llself: val_self_pair) {
51005140
}
51015141
i = 0;
51025142
for f: ast::obj_field in fcx.lcx.obj_fields {
5143+
// FIXME: silly check
5144+
check type_is_tup_like(bcx, fields_tup_ty);
51035145
let rslt = GEP_tup_like(bcx, fields_tup_ty, obj_fields, [0, i]);
51045146
bcx = llstaticallocas_block_ctxt(fcx);
51055147
let llfield = rslt.val;
@@ -5248,9 +5290,12 @@ fn trans_res_ctor(cx: @local_ctxt, sp: span, dtor: ast::_fn,
52485290
llretptr = BitCast(bcx, llretptr, llret_t);
52495291
}
52505292

5293+
// FIXME: silly checks
5294+
check type_is_tup_like(bcx, tup_t);
52515295
let dst = GEP_tup_like(bcx, tup_t, llretptr, [0, 1]);
52525296
bcx = dst.bcx;
52535297
bcx = copy_val(bcx, INIT, dst.val, arg, arg_t);
5298+
check type_is_tup_like(bcx, tup_t);
52545299
let flag = GEP_tup_like(bcx, tup_t, llretptr, [0, 0]);
52555300
bcx = flag.bcx;
52565301
Store(bcx, C_int(1), flag.val);

src/comp/middle/trans_alt.rs

+8
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,8 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
342342
for field_name: ast::ident in rec_fields {
343343
let ix: uint =
344344
ty::field_idx(ccx.sess, dummy_sp(), field_name, fields);
345+
// not sure how to get rid of this check
346+
check type_is_tup_like(bcx, rec_ty);
345347
let r = trans::GEP_tup_like(bcx, rec_ty, val, [0, ix as int]);
346348
rec_vals += [r.val];
347349
bcx = r.bcx;
@@ -359,6 +361,8 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
359361
};
360362
let tup_vals = [], i = 0u;
361363
while i < n_tup_elts {
364+
// how to get rid of this check?
365+
check type_is_tup_like(bcx, tup_ty);
362366
let r = trans::GEP_tup_like(bcx, tup_ty, val, [0, i as int]);
363367
tup_vals += [r.val];
364368
bcx = r.bcx;
@@ -603,6 +607,8 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: @ast::pat, val: ValueRef,
603607
for f: ast::field_pat in fields {
604608
let ix: uint =
605609
ty::field_idx(ccx.sess, pat.span, f.ident, rec_fields);
610+
// how to get rid of this check?
611+
check type_is_tup_like(bcx, rec_ty);
606612
let r = trans::GEP_tup_like(bcx, rec_ty, val, [0, ix as int]);
607613
bcx = bind_irrefutable_pat(r.bcx, f.pat, r.val, table, make_copy);
608614
}
@@ -611,6 +617,8 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: @ast::pat, val: ValueRef,
611617
let tup_ty = ty::node_id_to_monotype(ccx.tcx, pat.id);
612618
let i = 0u;
613619
for elem in elems {
620+
// how to get rid of this check?
621+
check type_is_tup_like(bcx, tup_ty);
614622
let r = trans::GEP_tup_like(bcx, tup_ty, val, [0, i as int]);
615623
bcx = bind_irrefutable_pat(r.bcx, elem, r.val, table, make_copy);
616624
i += 1u;

src/comp/middle/trans_objects.rs

+16
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,14 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id,
121121
// the types of the object's fields, so that the fields can be freed
122122
// later.
123123

124+
// postcondition on create_object_body_type?
125+
check type_is_tup_like(bcx, body_ty);
124126
let body_tydesc =
125127
GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_tydesc]);
126128
bcx = body_tydesc.bcx;
127129
let ti = none;
128130

131+
check type_is_tup_like(bcx, body_ty);
129132
let r =
130133
GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_typarams]);
131134
bcx = r.bcx;
@@ -151,6 +154,8 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id,
151154
let i: int = 0;
152155
for tp: ast::ty_param in ty_params {
153156
let typaram = bcx.fcx.lltydescs[i];
157+
// Silly check
158+
check type_is_tup_like(bcx, typarams_ty);
154159
let capture =
155160
GEP_tup_like(bcx, typarams_ty, body_typarams, [0, i]);
156161
bcx = capture.bcx;
@@ -159,6 +164,8 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id,
159164
}
160165

161166
// Copy args into body fields.
167+
// how to get rid of this check?
168+
check type_is_tup_like(bcx, body_ty);
162169
let body_fields =
163170
GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_fields]);
164171
bcx = body_fields.bcx;
@@ -169,6 +176,8 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id,
169176
let arg = load_if_immediate(bcx, arg1, arg_tys[i].ty);
170177
// TODO: can we just get fields_ty out of body_ty instead?
171178
let fields_ty: ty::t = ty::mk_tup(ccx.tcx, obj_fields);
179+
// Silly check
180+
check type_is_tup_like(bcx, fields_ty);
172181
let field =
173182
GEP_tup_like(bcx, fields_ty, body_fields.val, [0, i]);
174183
bcx = field.bcx;
@@ -314,6 +323,8 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: span, anon_obj: ast::anon_obj,
314323
// the user of the object. So the tydesc is needed to keep track of
315324
// the types of the object's fields, so that the fields can be freed
316325
// later.
326+
// postcondition on create_object_body_type?
327+
check type_is_tup_like(bcx, body_ty);
317328
let body_tydesc =
318329
GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_tydesc]);
319330
bcx = body_tydesc.bcx;
@@ -328,6 +339,7 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: span, anon_obj: ast::anon_obj,
328339
// body. (This is something like saving the lexical environment of a
329340
// function in its closure: the fields were passed to the object
330341
// constructor and are now available to the object's methods.
342+
check type_is_tup_like(bcx, body_ty);
331343
let body_fields =
332344
GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_fields]);
333345
bcx = body_fields.bcx;
@@ -338,6 +350,8 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: span, anon_obj: ast::anon_obj,
338350
load_if_immediate(bcx, additional_field_vals[i].val,
339351
additional_field_tys[i]);
340352
let fields_ty: ty::t = ty::mk_tup(ccx.tcx, additional_field_tys);
353+
// Silly check
354+
check type_is_tup_like(bcx, fields_ty);
341355
let field = GEP_tup_like(bcx, fields_ty, body_fields.val, [0, i]);
342356
bcx = field.bcx;
343357
bcx =
@@ -356,6 +370,7 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: span, anon_obj: ast::anon_obj,
356370
// value) wrapped in a result.
357371
let inner_obj_val: result = trans_expr(bcx, e);
358372

373+
check type_is_tup_like(bcx, body_ty);
359374
let body_inner_obj =
360375
GEP_tup_like(bcx, body_ty, body,
361376
[0, abi::obj_body_elt_inner_obj]);
@@ -776,6 +791,7 @@ fn process_fwding_mthd(cx: @local_ctxt, sp: span, m: @ty::method,
776791
T_ptr(type_of(cx_ccx, sp, body_ty)));
777792

778793
// Now, reach into the body and grab the inner_obj.
794+
check type_is_tup_like(bcx, body_ty);
779795
let llinner_obj =
780796
GEP_tup_like(bcx, body_ty, llself_obj_body,
781797
[0, abi::obj_body_elt_inner_obj]);

0 commit comments

Comments
 (0)