@@ -697,7 +697,8 @@ let condition_assigning_visitor
697
697
| Ast. STMT_while sw ->
698
698
let (_, expr) = sw.Ast. while_lval in
699
699
let precond = slot_inits (expr_slots cx expr) in
700
- raise_pre_post_cond s.id precond
700
+ raise_precondition sw.Ast. while_body.id precond;
701
+ raise_postcondition sw.Ast. while_body.id precond
701
702
702
703
| Ast. STMT_alt_tag at ->
703
704
let precond = slot_inits (lval_slots cx at.Ast. alt_tag_lval) in
@@ -947,16 +948,17 @@ let graph_special_block_structure_building_visitor
947
948
let ts = tables () in
948
949
let graph = ts.ts_graph in
949
950
let cond_id = s.id in
951
+ let succ = Hashtbl. find graph cond_id in
950
952
let then_id = sif.Ast. if_then.id in
951
953
let then_end_id = last_id_or_block_id sif.Ast. if_then in
952
954
let show_node = show_node cx graph in
955
+ let succ = List. filter (fun x -> not (x = then_id)) succ in
953
956
show_node " initial cond" cond_id;
954
957
show_node " initial then" then_id;
955
958
show_node " initial then_end" then_end_id;
956
959
begin
957
960
match sif.Ast. if_else with
958
961
None ->
959
- let succ = Hashtbl. find graph then_end_id in
960
962
Hashtbl. replace graph cond_id (then_id :: succ);
961
963
(* Kill residual messed-up block wiring.*)
962
964
remove_flow_edges graph then_end_id [then_id];
@@ -966,8 +968,10 @@ let graph_special_block_structure_building_visitor
966
968
967
969
| Some e ->
968
970
let else_id = e.id in
971
+ let succ =
972
+ List. filter (fun x -> not (x = else_id)) succ
973
+ in
969
974
let else_end_id = last_id_or_block_id e in
970
- let succ = Hashtbl. find graph else_end_id in
971
975
show_node " initial else" else_id;
972
976
show_node " initial else_end" else_end_id;
973
977
Hashtbl. replace graph cond_id [then_id; else_id];
@@ -1049,19 +1053,23 @@ let graph_special_block_structure_building_visitor
1049
1053
;;
1050
1054
1051
1055
let find_roots
1056
+ (cx :ctxt )
1052
1057
(graph :(node_id, (node_id list) ) Hashtbl. t )
1053
1058
: (node_id,unit) Hashtbl.t =
1054
1059
let roots = Hashtbl. create 0 in
1055
1060
Hashtbl. iter (fun src _ -> Hashtbl. replace roots src () ) graph;
1056
1061
Hashtbl. iter (fun _ dsts ->
1057
1062
List. iter (fun d -> Hashtbl. remove roots d) dsts) graph;
1063
+ iflog cx
1064
+ (fun _ -> Hashtbl. iter
1065
+ (fun k _ -> log cx " root: %d" (int_of_node k)) roots);
1058
1066
roots
1059
1067
;;
1060
1068
1061
1069
let run_dataflow (cx :ctxt ) (ts :typestate_tables ) : unit =
1062
1070
let graph = ts.ts_graph in
1063
1071
let idref = ts.ts_maxid in
1064
- let roots = find_roots graph in
1072
+ let roots = find_roots cx graph in
1065
1073
let nodes = Queue. create () in
1066
1074
1067
1075
let progress = ref true in
@@ -1138,9 +1146,17 @@ let run_dataflow (cx:ctxt) (ts:typestate_tables) : unit =
1138
1146
begin
1139
1147
fun _ ->
1140
1148
log cx " stmt %d: '%s'" (int_of_node node)
1141
- (match htab_search cx.ctxt_all_stmts node with
1142
- None -> " ??"
1143
- | Some stmt -> Fmt. fmt_to_str Ast. fmt_stmt stmt);
1149
+ begin
1150
+ match htab_search cx.ctxt_all_stmts node with
1151
+ None ->
1152
+ begin
1153
+ match htab_search cx.ctxt_all_blocks node with
1154
+ None -> " ??"
1155
+ | Some b ->
1156
+ Fmt. fmt_to_str Ast. fmt_block b
1157
+ end
1158
+ | Some stmt -> Fmt. fmt_to_str Ast. fmt_stmt stmt
1159
+ end ;
1144
1160
log cx " stmt %d:" (int_of_node node);
1145
1161
1146
1162
log cx " prestate %s" (fmt_constr_bitv prestate);
@@ -1227,27 +1243,35 @@ let typestate_verify_visitor
1227
1243
1228
1244
let tables _ = Stack. top tables_stack in
1229
1245
1230
- let visit_stmt_pre s =
1246
+ let check_states id =
1231
1247
let ts = tables () in
1232
- let prestate = Hashtbl. find ts.ts_prestates s. id in
1233
- let precond = Hashtbl. find ts.ts_preconditions s. id in
1248
+ let prestate = Hashtbl. find ts.ts_prestates id in
1249
+ let precond = Hashtbl. find ts.ts_preconditions id in
1234
1250
List. iter
1235
1251
(fun i ->
1236
1252
if not (Bits. get prestate i)
1237
1253
then
1238
1254
let ckey = Hashtbl. find ts.ts_constrs (Constr i) in
1239
1255
let constr_str = fmt_constr_key cx ckey in
1240
- err (Some s.id)
1241
- " Unsatisfied precondition constraint %s at stmt %d: %s"
1242
- constr_str
1243
- (int_of_node s.id)
1244
- (Fmt. fmt_to_str Ast. fmt_stmt
1245
- (Hashtbl. find cx.ctxt_all_stmts s.id)))
1246
- (Bits. to_list precond);
1247
- inner.Walk. visit_stmt_pre s
1256
+ err (Some id)
1257
+ " Unsatisfied precondition constraint %s"
1258
+ constr_str)
1259
+ (Bits. to_list precond)
1260
+ in
1261
+
1262
+ let visit_stmt_pre s =
1263
+ check_states s.id;
1264
+ inner.Walk. visit_stmt_pre s
1265
+ in
1266
+
1267
+ let visit_block_pre b =
1268
+ check_states b.id;
1269
+ inner.Walk. visit_block_pre b
1248
1270
in
1271
+
1249
1272
{ inner with
1250
- Walk. visit_stmt_pre = visit_stmt_pre }
1273
+ Walk. visit_stmt_pre = visit_stmt_pre;
1274
+ Walk. visit_block_pre = visit_block_pre }
1251
1275
;;
1252
1276
1253
1277
let lifecycle_visitor
0 commit comments