Skip to content

Commit 85b5b2a

Browse files
committed
Tests for while loops that may invalidate constraints
Wrote some small test cases that use while loops and moves, to make sure the poststate for the loop body gets propagated into the new prestate and deinitialization gets reflected. Along with that, rewrite the code for intersecting states. I still find it dodgy, but I guess I'll continue trying to add more tests. Also, I'll probably feel better about it once I start formalizing the algorithm.
1 parent 6d1050b commit 85b5b2a

File tree

9 files changed

+200
-96
lines changed

9 files changed

+200
-96
lines changed

src/comp/middle/tstate/ann.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ fn set_in_postcond(uint i, &pre_and_post p) -> bool {
112112
// sets the ith bit in p's post
113113
auto was_set = tritv_get(p.postcondition, i);
114114
tritv_set(i, p.postcondition, ttrue);
115-
ret was_set == dont_care;
115+
ret was_set != ttrue;
116116
}
117117

118118
fn set_in_poststate(uint i, &pre_and_post_state s) -> bool {
@@ -123,7 +123,7 @@ fn set_in_poststate(uint i, &pre_and_post_state s) -> bool {
123123
fn set_in_poststate_(uint i, &poststate p) -> bool {
124124
auto was_set = tritv_get(p, i);
125125
tritv_set(i, p, ttrue);
126-
ret was_set == dont_care;
126+
ret was_set != ttrue;
127127

128128
}
129129

@@ -135,14 +135,25 @@ fn clear_in_poststate(uint i, &pre_and_post_state s) -> bool {
135135
fn clear_in_poststate_(uint i, &poststate s) -> bool {
136136
auto was_set = tritv_get(s, i);
137137
tritv_set(i, s, tfalse);
138-
ret was_set == dont_care;
138+
ret was_set != tfalse;
139+
}
140+
141+
fn clear_in_prestate(uint i, &pre_and_post_state s) -> bool {
142+
// sets the ith bit in p's pre
143+
ret clear_in_prestate_(i, s.prestate);
144+
}
145+
146+
fn clear_in_prestate_(uint i, &prestate s) -> bool {
147+
auto was_set = tritv_get(s, i);
148+
tritv_set(i, s, tfalse);
149+
ret was_set != tfalse;
139150
}
140151

141152
fn clear_in_postcond(uint i, &pre_and_post s) -> bool {
142153
// sets the ith bit in p's post
143154
auto was_set = tritv_get(s.postcondition, i);
144155
tritv_set(i, s.postcondition, tfalse);
145-
ret was_set == dont_care;
156+
ret was_set != tfalse;
146157
}
147158

148159
// Sets all the bits in a's precondition to equal the

src/comp/middle/tstate/bitvectors.rs

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import tstate::ann::set_in_postcond;
4343
import tstate::ann::set_in_poststate;
4444
import tstate::ann::set_in_poststate_;
4545
import tstate::ann::clear_in_poststate;
46+
import tstate::ann::clear_in_prestate;
4647
import tstate::ann::clear_in_poststate_;
4748
import tritv::*;
4849

@@ -147,22 +148,10 @@ fn seq_preconds(&fn_ctxt fcx, &vec[pre_and_post] pps) -> precond {
147148
} else { ret true_precond(num_vars); }
148149
}
149150

150-
/* Gee, maybe we could use foldl or something */
151-
fn intersect_postconds_go(&postcond first, &vec[postcond] rest) -> postcond {
152-
auto sz = vec::len[postcond](rest);
153-
if (sz > 0u) {
154-
auto other = rest.(0);
155-
intersect(first, other);
156-
intersect_postconds_go(first,
157-
slice[postcond](rest, 1u,
158-
len[postcond](rest)));
159-
}
160-
ret first;
161-
}
162-
163-
fn intersect_postconds(&vec[postcond] pcs) -> postcond {
164-
assert (len[postcond](pcs) > 0u);
165-
ret intersect_postconds_go(tritv_clone(pcs.(0)), pcs);
151+
fn intersect_states(&prestate p, &prestate q) -> prestate {
152+
auto rslt = tritv_clone(p);
153+
tritv_intersect(rslt, q);
154+
ret rslt;
166155
}
167156

168157
fn gen(&fn_ctxt fcx, node_id id, &constr_ c) -> bool {
@@ -219,6 +208,11 @@ fn gen_poststate(&fn_ctxt fcx, node_id id, &constr_ c) -> bool {
219208
node_id_to_ts_ann(fcx.ccx, id).states);
220209
}
221210

211+
fn kill_prestate(&fn_ctxt fcx, node_id id, &constr_ c) -> bool {
212+
ret clear_in_prestate(bit_num(fcx, c),
213+
node_id_to_ts_ann(fcx.ccx, id).states);
214+
}
215+
222216
fn kill_poststate(&fn_ctxt fcx, node_id id, &constr_ c) -> bool {
223217
log "kill_poststate";
224218
ret clear_in_poststate(bit_num(fcx, c),
@@ -254,6 +248,16 @@ fn set_in_poststate_ident(&fn_ctxt fcx, &node_id id, &ident ident,
254248
ret set_in_poststate_(bit_num(fcx, rec(id=id, c=ninit(ident))), t);
255249
}
256250

251+
fn clear_in_poststate_ident(&fn_ctxt fcx, &node_id id, &ident ident,
252+
&node_id parent) -> bool {
253+
ret kill_poststate(fcx, parent, rec(id=id, c=ninit(ident)));
254+
}
255+
256+
fn clear_in_prestate_ident(&fn_ctxt fcx, &node_id id, &ident ident,
257+
&node_id parent) -> bool {
258+
ret kill_prestate(fcx, parent, rec(id=id, c=ninit(ident)));
259+
}
260+
257261
//
258262
// Local Variables:
259263
// mode: rust

src/comp/middle/tstate/ck.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@ fn check_states_expr(&fn_ctxt fcx, &@expr e) {
7070
log_err("check_states_expr:");
7171
util::common::log_expr_err(*e);
7272
log_err("prec = ");
73-
log_bitv_err(fcx, prec);
73+
log_tritv_err(fcx, prec);
7474
log_err("pres = ");
75-
log_bitv_err(fcx, pres);
75+
log_tritv_err(fcx, pres);
7676
*/
7777

7878
if (!implies(pres, prec)) {
@@ -99,9 +99,9 @@ fn check_states_stmt(&fn_ctxt fcx, &@stmt s) {
9999
log_err("check_states_stmt:");
100100
log_stmt_err(*s);
101101
log_err("prec = ");
102-
log_bitv_err(fcx, prec);
102+
log_tritv_err(fcx, prec);
103103
log_err("pres = ");
104-
log_bitv_err(fcx, pres);
104+
log_tritv_err(fcx, pres);
105105
*/
106106

107107
if (!implies(pres, prec)) {

src/comp/middle/tstate/pre_post_conditions.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ import bitvectors::bit_num;
5959
import bitvectors::promises;
6060
import bitvectors::seq_preconds;
6161
import bitvectors::seq_postconds;
62-
import bitvectors::intersect_postconds;
62+
import bitvectors::intersect_states;
6363
import bitvectors::declare_var;
6464
import bitvectors::gen_poststate;
6565
import bitvectors::relax_precond_block;
@@ -180,9 +180,8 @@ fn find_pre_post_loop(&fn_ctxt fcx, &@local l, &@expr index, &block body,
180180
seq_preconds(fcx,
181181
[expr_pp(fcx.ccx, index),
182182
block_pp(fcx.ccx, body)]);
183-
auto loop_postcond =
184-
intersect_postconds([expr_postcond(fcx.ccx, index),
185-
block_postcond(fcx.ccx, body)]);
183+
auto loop_postcond = intersect_states(expr_postcond(fcx.ccx, index),
184+
block_postcond(fcx.ccx, body));
186185
copy_pre_post_(fcx.ccx, id, loop_precond, loop_postcond);
187186
}
188187

@@ -247,8 +246,7 @@ fn join_then_else(&fn_ctxt fcx, &@expr antec, &block conseq,
247246
seq_postconds(fcx, [precond_true_case,
248247
precond_false_case]);
249248
auto postcond_res =
250-
intersect_postconds([postcond_true_case,
251-
postcond_false_case]);
249+
intersect_states(postcond_true_case, postcond_false_case);
252250
set_pre_and_post(fcx.ccx, id, precond_res, postcond_res);
253251
}
254252
}
@@ -459,10 +457,9 @@ fn find_pre_post_expr(&fn_ctxt fcx, @expr e) {
459457
seq_preconds(fcx,
460458
[expr_pp(fcx.ccx, test),
461459
block_pp(fcx.ccx, body)]),
462-
intersect_postconds([expr_postcond(fcx.ccx,
463-
test),
464-
block_postcond(fcx.ccx,
465-
body)]));
460+
intersect_states(expr_postcond(fcx.ccx, test),
461+
block_postcond(fcx.ccx,
462+
body)));
466463
}
467464
case (expr_do_while(?body, ?test)) {
468465
find_pre_post_block(fcx, body);

0 commit comments

Comments
 (0)