Skip to content

Commit 0208722

Browse files
committed
---
yaml --- r: 2697 b: refs/heads/master c: 755ca8e h: refs/heads/master i: 2695: 548c181 v: v3
1 parent a3f069c commit 0208722

File tree

6 files changed

+41
-3
lines changed

6 files changed

+41
-3
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 699986d192a90313cb1fdaf1a650247689a13cee
2+
refs/heads/master: 755ca8eb73e0bd8cb9df892973a3bb5faf3fd651

trunk/src/comp/middle/tstate/ann.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,13 @@ fn set_in_poststate(uint i, &pre_and_post_state s) -> bool {
109109
ret !was_set;
110110
}
111111

112+
fn clear_in_poststate(uint i, &pre_and_post_state s) -> bool {
113+
// sets the ith bit in p's post
114+
auto was_set = bitv::get(s.poststate, i);
115+
bitv::set(s.poststate, i, false);
116+
ret was_set;
117+
}
118+
112119
// Sets all the bits in a's precondition to equal the
113120
// corresponding bit in p's precondition.
114121
fn set_precondition(ts_ann a, &precond p) -> () {

trunk/src/comp/middle/tstate/bitvectors.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import tstate::ann::intersect;
2929
import tstate::ann::clone;
3030
import tstate::ann::set_in_postcond;
3131
import tstate::ann::set_in_poststate;
32+
import tstate::ann::clear_in_poststate;
3233

3334
fn bit_num(def_id v, fn_info m) -> uint {
3435
assert (m.vars.contains_key(v));
@@ -137,3 +138,10 @@ fn gen_poststate(&fn_ctxt fcx, &ann a, def_id id) -> bool {
137138
ret set_in_poststate(i, (ann_to_ts_ann(fcx.ccx, a)).states);
138139
}
139140

141+
fn kill_poststate(&fn_ctxt fcx, &ann a, def_id id) -> bool {
142+
log "kill_poststate";
143+
assert (fcx.enclosing.vars.contains_key(id));
144+
let uint i = (fcx.enclosing.vars.get(id))._0;
145+
ret clear_in_poststate(i, (ann_to_ts_ann(fcx.ccx, a)).states);
146+
}
147+

trunk/src/comp/middle/tstate/ck.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import front::ast::ident;
1111
import front::ast::def_id;
1212
import front::ast::ty_param;
1313
import front::ast::crate;
14+
import front::ast::return;
15+
import front::ast::noreturn;
1416

1517
import front::ast::expr;
1618
import middle::ty::type_is_nil;
@@ -124,17 +126,29 @@ fn check_states_against_conditions(&fn_ctxt fcx, &_fn f, &ann a) -> () {
124126
auto do_inner = bind do_inner_(fcx, _, post);
125127
option::map[@expr, ()](do_inner, f.body.node.expr);
126128

129+
auto cf = fcx.enclosing.cf;
127130
/* Finally, check that the return value is initialized */
128131
if (f.proto == ast::proto_fn
129132
&& ! promises(*post, fcx.id, enclosing)
130133
&& ! type_is_nil(fcx.ccx.tcx,
131-
ret_ty_of_fn(fcx.ccx.tcx, a)) ) {
134+
ret_ty_of_fn(fcx.ccx.tcx, a))
135+
&& cf == return) {
132136
fcx.ccx.tcx.sess.span_note(f.body.span, "In function " + fcx.name +
133137
", not all control paths return a value");
134138
fcx.ccx.tcx.sess.span_err(f.decl.output.span,
135139
"see declared return type of '" + ty_to_str(*f.decl.output) +
136140
"'");
137141
}
142+
else if (cf == noreturn) {
143+
// check that this really always fails
144+
// the fcx.id bit means "returns" for a returning fn,
145+
// "diverges" for a non-returning fn (I need to use the word
146+
if (! promises(*post, fcx.id, enclosing)) {
147+
fcx.ccx.tcx.sess.span_err(f.body.span,
148+
"In non-returning function " + fcx.name +
149+
", some control paths may return to the caller");
150+
}
151+
}
138152

139153
}
140154

trunk/src/comp/middle/tstate/states.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ import bitvectors::intersect_postconds;
5656
import bitvectors::declare_var;
5757
import bitvectors::bit_num;
5858
import bitvectors::gen_poststate;
59+
import bitvectors::kill_poststate;
5960

6061
import front::ast;
6162
import front::ast::_fn;
@@ -373,6 +374,13 @@ fn find_pre_post_state_expr(&fn_ctxt fcx, &prestate pres, @expr e) -> bool {
373374
case (expr_ret(?maybe_ret_val, ?a)) {
374375
changed = extend_prestate_ann(fcx.ccx, a, pres) || changed;
375376
set_poststate_ann(fcx.ccx, a, false_postcond(num_local_vars));
377+
/* return from an always-failing function clears the return bit */
378+
alt (fcx.enclosing.cf) {
379+
case (noreturn) {
380+
kill_poststate(fcx, a, fcx.id);
381+
}
382+
case (_) {}
383+
}
376384
alt(maybe_ret_val) {
377385
case (none[@expr]) { /* do nothing */ }
378386
case (some[@expr](?ret_val)) {

trunk/src/comp/middle/ty.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2288,7 +2288,8 @@ mod unify {
22882288

22892289
alt (struct(cx.tcx, expected)) {
22902290
case (ty::ty_nil) { ret struct_cmp(cx, expected, actual); }
2291-
case (ty::ty_bot) { ret struct_cmp(cx, expected, actual); }
2291+
// _|_ unifies with anything
2292+
case (ty::ty_bot) { ret ures_ok(expected); }
22922293
case (ty::ty_bool) { ret struct_cmp(cx, expected, actual); }
22932294
case (ty::ty_int) { ret struct_cmp(cx, expected, actual); }
22942295
case (ty::ty_uint) { ret struct_cmp(cx, expected, actual); }

0 commit comments

Comments
 (0)