diff --git a/infer/src/IR/cfg.ml b/infer/src/IR/cfg.ml
index e19ab4d5e..167187ffd 100644
--- a/infer/src/IR/cfg.ml
+++ b/infer/src/IR/cfg.ml
@@ -17,6 +17,8 @@ module F = Format
(* =============== START of module Node =============== *)
module Node = struct
+ type id = int
+
type nodekind =
| Start_node of proc_desc
| Exit_node of proc_desc
@@ -27,7 +29,7 @@ module Node = struct
and t = { (** a node *)
(** unique id of the node *)
- nd_id : int;
+ nd_id : id;
(** distance to the exit node *)
mutable nd_dist_exit : int option;
@@ -204,6 +206,9 @@ module Node = struct
(** Get the unique id of the node *)
let get_id node = node.nd_id
+ (** compare node ids *)
+ let id_compare = int_compare
+
let get_succs node = node.nd_succs
type node = t
diff --git a/infer/src/IR/cfg.mli b/infer/src/IR/cfg.mli
index 872395313..3d17182da 100644
--- a/infer/src/IR/cfg.mli
+++ b/infer/src/IR/cfg.mli
@@ -127,6 +127,8 @@ end
module Node : sig
type t = node (** type of nodes *)
+ type id = private int
+
(** kind of cfg node *)
type nodekind =
| Start_node of Procdesc.t
@@ -192,7 +194,10 @@ module Node : sig
val get_exn : t -> t list
(** Get the unique id of the node *)
- val get_id : t -> int
+ val get_id : t -> id
+
+ (** compare node ids *)
+ val id_compare : id -> id -> int
(** Get the source location of the node *)
val get_loc : t -> Location.t
diff --git a/infer/src/backend/dotty.ml b/infer/src/backend/dotty.ml
index 337fd8a32..6195035f9 100644
--- a/infer/src/backend/dotty.ml
+++ b/infer/src/backend/dotty.ml
@@ -924,7 +924,7 @@ let pp_proplist_parsed2dotty_file filename plist =
(* channel. You have to compute an interprocedural cfg first *)
let pp_cfgnodename fmt (n : Cfg.Node.t) =
- F.fprintf fmt "%d" (Cfg.Node.get_id n)
+ F.fprintf fmt "%d" (Cfg.Node.get_id n :> int)
let pp_etlist fmt etl =
IList.iter (fun (id, ty) ->
@@ -962,7 +962,7 @@ let pp_cfgnodelabel fmt (n : Cfg.Node.t) =
let pp_instrs fmt instrs =
IList.iter (fun i -> F.fprintf fmt " %s\\n " (instr_string i)) instrs in
let instrs = Cfg.Node.get_instrs n in
- F.fprintf fmt "%d: %a \\n %a" (Cfg.Node.get_id n) pp_label n pp_instrs instrs
+ F.fprintf fmt "%d: %a \\n %a" (Cfg.Node.get_id n :> int) pp_label n pp_instrs instrs
let pp_cfgnodeshape fmt (n: Cfg.Node.t) =
match Cfg.Node.get_kind n with
@@ -987,7 +987,10 @@ let pp_cfgnode fmt (n: Cfg.Node.t) =
| Cfg.Node.Exit_node _ when is_exn = true -> (* don't print exception edges to the exit node *)
()
| _ ->
- F.fprintf fmt "\n\t %d -> %d %s;" (Cfg.Node.get_id n1) (Cfg.Node.get_id n2) color in
+ F.fprintf fmt "\n\t %d -> %d %s;"
+ (Cfg.Node.get_id n1 :> int)
+ (Cfg.Node.get_id n2 :> int)
+ color in
IList.iter (fun n' -> print_edge n n' false) (Cfg.Node.get_succs n);
IList.iter (fun n' -> print_edge n n' true) (Cfg.Node.get_exn n)
diff --git a/infer/src/backend/errdesc.ml b/infer/src/backend/errdesc.ml
index 8f6ab03ed..26fd92a89 100644
--- a/infer/src/backend/errdesc.ml
+++ b/infer/src/backend/errdesc.ml
@@ -115,7 +115,7 @@ let find_normal_variable_funcall
("find_normal_variable_funcall could not find " ^
Ident.to_string id ^
" in node " ^
- string_of_int (Cfg.Node.get_id node));
+ string_of_int (Cfg.Node.get_id node :> int));
L.d_ln ());
!res
@@ -257,7 +257,7 @@ let rec _find_normal_variable_letderef (seen : Sil.ExpSet.t) node id : Sil.dexp
("find_normal_variable_letderef could not find " ^
Ident.to_string id ^
" in node " ^
- string_of_int (Cfg.Node.get_id node));
+ string_of_int (Cfg.Node.get_id node :> int));
L.d_ln ());
!res
diff --git a/infer/src/backend/interproc.ml b/infer/src/backend/interproc.ml
index 31bc28826..370c9f736 100644
--- a/infer/src/backend/interproc.ml
+++ b/infer/src/backend/interproc.ml
@@ -58,15 +58,12 @@ module NodeVisitSet =
(** Table for the results of the join operation on nodes. *)
module Join_table : sig
type t
- type node_id = int
- val add : t -> node_id -> Paths.PathSet.t -> unit
+ val add : t -> Cfg.Node.id -> Paths.PathSet.t -> unit
val create : unit -> t
- val find : t -> node_id -> Paths.PathSet.t
+ val find : t -> Cfg.Node.id -> Paths.PathSet.t
end = struct
- type t = (int, Paths.PathSet.t) Hashtbl.t
-
- type node_id = int
+ type t = (Cfg.Node.id, Paths.PathSet.t) Hashtbl.t
let create () : t =
Hashtbl.create 11
@@ -83,14 +80,12 @@ end
module Worklist = struct
module NodeMap = Map.Make(Cfg.Node)
- type node_id = int
-
type t = {
join_table : Join_table.t; (** Table of join results *)
- path_set_todo : (node_id, Paths.PathSet.t) Hashtbl.t; (** Pathset todo *)
- path_set_visited : (node_id, Paths.PathSet.t) Hashtbl.t; (** Pathset visited *)
+ path_set_todo : (Cfg.Node.id, Paths.PathSet.t) Hashtbl.t; (** Pathset todo *)
+ path_set_visited : (Cfg.Node.id, Paths.PathSet.t) Hashtbl.t; (** Pathset visited *)
mutable todo_set : NodeVisitSet.t; (** Set of nodes still to do, with visit count *)
- mutable visit_map : node_id NodeMap.t; (** Map from nodes done to visit count *)
+ mutable visit_map : int NodeMap.t; (** Map from nodes done to visit count *)
}
let create () = {
@@ -132,7 +127,8 @@ let path_set_create_worklist pdesc =
Cfg.Procdesc.compute_distance_to_exit_node pdesc;
Worklist.create ()
-let htable_retrieve (htable : (int, Paths.PathSet.t) Hashtbl.t) (key : int) : Paths.PathSet.t =
+let htable_retrieve (htable : (Cfg.Node.id, Paths.PathSet.t) Hashtbl.t) (key : Cfg.Node.id)
+ : Paths.PathSet.t =
try
Hashtbl.find htable key
with Not_found ->
@@ -344,7 +340,7 @@ let do_before_node session node =
State.set_node node;
State.set_session session;
L.reset_delayed_prints ();
- Printer.node_start_session node loc proc_name session
+ Printer.node_start_session node loc proc_name (session :> int)
let do_after_node node =
Printer.node_finish_session node
@@ -493,9 +489,9 @@ let mark_visited summary node =
let stats = summary.Specs.stats in
if !Config.footprint
then
- stats.Specs.nodes_visited_fp <- IntSet.add node_id stats.Specs.nodes_visited_fp
+ stats.Specs.nodes_visited_fp <- IntSet.add (node_id :> int) stats.Specs.nodes_visited_fp
else
- stats.Specs.nodes_visited_re <- IntSet.add node_id stats.Specs.nodes_visited_re
+ stats.Specs.nodes_visited_re <- IntSet.add (node_id :> int) stats.Specs.nodes_visited_re
let forward_tabulate tenv wl =
let handled_some_exception = ref false in
@@ -549,7 +545,7 @@ let forward_tabulate tenv wl =
handled_some_exception := false;
check_prop_size pathset_todo;
L.d_strln ("**** " ^ (log_string proc_name) ^ " " ^
- "Node: " ^ string_of_int curr_node_id ^ ", " ^
+ "Node: " ^ string_of_int (curr_node_id :> int) ^ ", " ^
"Procedure: " ^ Procname.to_string proc_name ^ ", " ^
"Session: " ^ string_of_int session ^ ", " ^
"Todo: " ^ string_of_int (Paths.PathSet.size pathset_todo) ^ " ****");
diff --git a/infer/src/backend/paths.ml b/infer/src/backend/paths.ml
index f1bae8ffd..ba03fb5ab 100644
--- a/infer/src/backend/paths.ml
+++ b/infer/src/backend/paths.ml
@@ -271,7 +271,7 @@ end = struct
let get_path_pos node =
let pn = Cfg.Procdesc.get_proc_name (Cfg.Node.get_proc_desc node) in
let n_id = Cfg.Node.get_id node in
- (pn, n_id)
+ (pn, (n_id :> int))
let contains_position path pos =
let found = ref false in
@@ -291,10 +291,13 @@ end = struct
| Pstart _ -> f level path session prev_exn_opt
| Pnode (_, exn_opt, session', p, _, _) ->
let next_exn_opt = if prev_exn_opt <> None then None else exn_opt in (* no two consecutive exceptions *)
- doit level session' p next_exn_opt;
+ doit level (session' :> int) p next_exn_opt;
f level path session prev_exn_opt
| Pjoin (p1, p2, _) ->
- if (Invariant.get_stats p1).max_length >= (Invariant.get_stats p2).max_length then doit level session p1 prev_exn_opt else doit level session p2 prev_exn_opt
+ if (Invariant.get_stats p1).max_length >= (Invariant.get_stats p2).max_length then
+ doit level session p1 prev_exn_opt
+ else
+ doit level session p2 prev_exn_opt
| Pcall (p1, _, p2, _) ->
let next_exn_opt = None in (* exn must already be inside the call *)
doit level session p1 next_exn_opt;
@@ -367,7 +370,7 @@ end = struct
"linear paths: " ^ string_of_float (Invariant.get_stats path).linear_num ^
" max length: " ^ string_of_int (Invariant.get_stats path).max_length ^
" has repetitions: " ^ string_of_int repetitions ^
- " of node " ^ (string_of_int (Cfg.Node.get_id node)) in
+ " of node " ^ (string_of_int (Cfg.Node.get_id node :> int)) in
Invariant.reset_stats path;
str
@@ -411,7 +414,7 @@ end = struct
| Pstart (node, _) ->
F.fprintf fmt "n%a" Cfg.Node.pp node
| Pnode (node, _, session, path, _, _) ->
- F.fprintf fmt "%a(s%d).n%a" (doit (n - 1)) path session Cfg.Node.pp node
+ F.fprintf fmt "%a(s%d).n%a" (doit (n - 1)) path (session :> int) Cfg.Node.pp node
| Pjoin (path1, path2, _) ->
F.fprintf fmt "(%a + %a)" (doit (n - 1)) path1 (doit (n - 1)) path2
| Pcall (path1, _, path2, _) ->
diff --git a/infer/src/backend/printer.ml b/infer/src/backend/printer.ml
index 0cc5344fb..987844ea6 100644
--- a/infer/src/backend/printer.ml
+++ b/infer/src/backend/printer.ml
@@ -86,9 +86,9 @@ let node_is_visited node =
| Some summary ->
let stats = summary.Specs.stats in
let is_visited_fp =
- IntSet.mem (Cfg.Node.get_id node) stats.Specs.nodes_visited_fp in
+ IntSet.mem (Cfg.Node.get_id node :> int) stats.Specs.nodes_visited_fp in
let is_visited_re =
- IntSet.mem (Cfg.Node.get_id node) stats.Specs.nodes_visited_re in
+ IntSet.mem (Cfg.Node.get_id node :> int) stats.Specs.nodes_visited_re in
is_visited_fp, is_visited_re
(** Return true if the node was visited during analysis *)
@@ -130,24 +130,24 @@ end = struct
F.fprintf fmt "
PREDS:@\n";
IList.iter (fun node ->
Io_infer.Html.pp_node_link [".."] ""
- (IList.map Cfg.Node.get_id (Cfg.Node.get_preds node))
- (IList.map Cfg.Node.get_id (Cfg.Node.get_succs node))
- (IList.map Cfg.Node.get_id (Cfg.Node.get_exn node))
- (is_visited node) false fmt (Cfg.Node.get_id node)) preds;
+ (IList.map Cfg.Node.get_id (Cfg.Node.get_preds node) :> int list)
+ (IList.map Cfg.Node.get_id (Cfg.Node.get_succs node) :> int list)
+ (IList.map Cfg.Node.get_id (Cfg.Node.get_exn node) :> int list)
+ (is_visited node) false fmt (Cfg.Node.get_id node :> int)) preds;
F.fprintf fmt "
SUCCS: @\n";
IList.iter (fun node ->
Io_infer.Html.pp_node_link [".."] ""
- (IList.map Cfg.Node.get_id (Cfg.Node.get_preds node))
- (IList.map Cfg.Node.get_id (Cfg.Node.get_succs node))
- (IList.map Cfg.Node.get_id (Cfg.Node.get_exn node))
- (is_visited node) false fmt (Cfg.Node.get_id node)) succs;
+ (IList.map Cfg.Node.get_id (Cfg.Node.get_preds node) :> int list)
+ (IList.map Cfg.Node.get_id (Cfg.Node.get_succs node) :> int list)
+ (IList.map Cfg.Node.get_id (Cfg.Node.get_exn node) :> int list)
+ (is_visited node) false fmt (Cfg.Node.get_id node :> int)) succs;
F.fprintf fmt "
EXN: @\n";
IList.iter (fun node ->
Io_infer.Html.pp_node_link [".."] ""
- (IList.map Cfg.Node.get_id (Cfg.Node.get_preds node))
- (IList.map Cfg.Node.get_id (Cfg.Node.get_succs node))
- (IList.map Cfg.Node.get_id (Cfg.Node.get_exn node))
- (is_visited node) false fmt (Cfg.Node.get_id node)) exn;
+ (IList.map Cfg.Node.get_id (Cfg.Node.get_preds node) :> int list)
+ (IList.map Cfg.Node.get_id (Cfg.Node.get_succs node) :> int list)
+ (IList.map Cfg.Node.get_id (Cfg.Node.get_exn node) :> int list)
+ (is_visited node) false fmt (Cfg.Node.get_id node :> int)) exn;
F.fprintf fmt "
@\n";
F.pp_print_flush fmt ();
true
@@ -360,7 +360,7 @@ let force_delayed_prints () =
let start_session node (loc: Location.t) proc_name session =
let node_id = Cfg.Node.get_id node in
(if NodesHtml.start_node
- node_id loc proc_name
+ (node_id :> int) loc proc_name
(Cfg.Node.get_preds node)
(Cfg.Node.get_succs node)
(Cfg.Node.get_exn node)
@@ -372,7 +372,7 @@ let start_session node (loc: Location.t) proc_name session =
F.fprintf !curr_html_formatter "%a%a"
Io_infer.Html.pp_hline ()
(Io_infer.Html.pp_session_link ~with_name: true [".."])
- (node_id, session, loc.Location.line);
+ ((node_id :> int), session, loc.Location.line);
F.fprintf !curr_html_formatter "