Fix assert false in Paths.

Reviewed By: akotulski

Differential Revision: D2585594

fb-gh-sync-id: a4ec077
master
Cristiano Calcagno 9 years ago committed by facebook-github-bot-1
parent 6a922ff597
commit 56ccb6b198

@ -35,11 +35,12 @@ let check_nested_loop path pos_opt =
incr trace_length;
(* L.d_strln ("level " ^ string_of_int level ^ " (Cfg.Node.get_id node) " ^ string_of_int nid); *)
() in
let f level p session exn_opt =
let node = Paths.Path.curr_node p in
do_any_node level node;
if level = 0 then do_node_caller node;
() in
let f level p session exn_opt = match Paths.Path.curr_node p with
| Some node ->
do_any_node level node;
if level = 0 then do_node_caller node
| None ->
() in
Paths.Path.iter_longest_sequence f pos_opt path;
in_nested_loop ()

@ -138,22 +138,26 @@ let path_set_checkout_todo (node: Cfg.node) : Paths.PathSet.t =
(* =============== START: Print a complete path in a dotty file =============== *)
let pp_path_dotty f path =
let get_node_id_from_path p =
let node = Paths.Path.curr_node p in
Cfg.Node.get_id node in
let count = ref 0 in
let prev_n_id = ref 0 in
let curr_n_id = ref 0 in
prev_n_id:=- 1;
let g level p session exn_opt =
let curr_node = Paths.Path.curr_node p in
let curr_path_set = htable_retrieve path_set_visited (Cfg.Node.get_id curr_node) in
let plist = Paths.PathSet.filter_path p curr_path_set in
incr count;
curr_n_id:= (get_node_id_from_path p);
Dotty.pp_dotty_prop_list_in_path f plist !prev_n_id !curr_n_id;
L.out "@.Path #%d: %a@." !count Paths.Path.pp p;
prev_n_id:=!curr_n_id in
let get_node_id_from_path p = match Paths.Path.curr_node p with
| Some node ->
Cfg.Node.get_id node
| None ->
!curr_n_id in
let g level p session exn_opt = match Paths.Path.curr_node p with
| Some curr_node ->
let curr_path_set = htable_retrieve path_set_visited (Cfg.Node.get_id curr_node) in
let plist = Paths.PathSet.filter_path p curr_path_set in
incr count;
curr_n_id := get_node_id_from_path p;
Dotty.pp_dotty_prop_list_in_path f plist !prev_n_id !curr_n_id;
L.out "@.Path #%d: %a@." !count Paths.Path.pp p;
prev_n_id:=!curr_n_id
| None ->
() in
L.out "@.@.Printing Path: %a to file error_path.dot@." Paths.Path.pp path;
Dotty.reset_proposition_counter ();
Dotty.reset_dotty_spec_counter ();
@ -335,18 +339,20 @@ let reset_prop_metrics () =
let d_path (path, pos_opt) =
let step = ref 0 in
let prop_last_step = ref Prop.prop_emp in (* if the last step had a singleton prop, store it here *)
let f level p session exn_opt =
let curr_node = Paths.Path.curr_node p in
let curr_path_set = htable_retrieve path_set_visited (Cfg.Node.get_id curr_node) in
let plist = Paths.PathSet.filter_path p curr_path_set in
incr step;
(* Propset.pp_proplist_dotty_file ("path" ^ (string_of_int !count) ^ ".dot") plist; *)
L.d_strln ("Path Step #" ^ string_of_int !step ^
" node " ^ string_of_int (Cfg.Node.get_id curr_node) ^
" session " ^ string_of_int session ^ ":");
Propset.d !prop_last_step (Propset.from_proplist plist); L.d_ln ();
Cfg.Node.d_instrs true None curr_node; L.d_ln (); L.d_ln ();
prop_last_step := (match plist with | [prop] -> prop | _ -> Prop.prop_emp) in
let f level p session exn_opt = match Paths.Path.curr_node p with
| Some curr_node ->
let curr_path_set = htable_retrieve path_set_visited (Cfg.Node.get_id curr_node) in
let plist = Paths.PathSet.filter_path p curr_path_set in
incr step;
(* Propset.pp_proplist_dotty_file ("path" ^ (string_of_int !count) ^ ".dot") plist; *)
L.d_strln ("Path Step #" ^ string_of_int !step ^
" node " ^ string_of_int (Cfg.Node.get_id curr_node) ^
" session " ^ string_of_int session ^ ":");
Propset.d !prop_last_step (Propset.from_proplist plist); L.d_ln ();
Cfg.Node.d_instrs true None curr_node; L.d_ln (); L.d_ln ();
prop_last_step := (match plist with | [prop] -> prop | _ -> Prop.prop_emp)
| None ->
() in
L.d_str "Path: "; Paths.Path.d_stats path; L.d_ln ();
Paths.Path.d path; L.d_ln ();
(* pp_complete_path_dotty_file path; *)

@ -35,7 +35,7 @@ module Path : sig
val create_loc_trace : t -> Sil.path_pos option -> Errlog.loc_trace
(** return the current node of the path *)
val curr_node : t -> Cfg.node
val curr_node : t -> Cfg.node option
(** dump a path *)
val d : t -> unit
@ -115,10 +115,11 @@ end = struct
stats.linear_num <- - 1.0
let rec curr_node = function
| Pstart (node, _) -> node
| Pnode (node, _, _, _, _, _) -> node
| Pstart (node, _) -> Some node
| Pnode (node, _, _, _, _, _) -> Some node
| Pcall(p1, _, _, _) -> curr_node p1
| Pjoin _ -> assert false
| Pjoin _ ->
None
let exname_opt_compare eo1 eo2 = match eo1, eo2 with
| None, None -> 0
@ -306,8 +307,10 @@ end = struct
| Some pos -> Sil.path_pos_equal (get_path_pos node) pos in
let path_pos_at_path p =
try
let node = curr_node p in
pos_opt <> None && filter node
match curr_node p with
| Some node ->
pos_opt <> None && filter node
| None -> false
with exn when exn_not_timeout exn -> false in
let position_seen = ref false in
let inverse_sequence =
@ -333,12 +336,17 @@ end = struct
(** return the node visited most, and number of visits, in the longest linear sequence *)
let repetitions path =
let map = ref NodeMap.empty in
let add_node node =
try
let n = NodeMap.find node !map in
map := NodeMap.add node (n + 1) !map
with Not_found ->
map := NodeMap.add node 1 !map in
let add_node = function
| Some node ->
begin
try
let n = NodeMap.find node !map in
map := NodeMap.add node (n + 1) !map
with Not_found ->
map := NodeMap.add node 1 !map
end
| None ->
() in
iter_longest_sequence (fun level p s exn_opt -> add_node (curr_node p)) None path;
let max_rep_node = ref (Cfg.Node.dummy ()) in
let max_rep_num = ref 0 in
@ -423,51 +431,69 @@ end = struct
Errlog.lt_description = descr;
Errlog.lt_node_tags = node_tags } in
let g level path session exn_opt =
let curr_node = curr_node path in
let curr_loc = Cfg.Node.get_loc curr_node in
match Cfg.Node.get_kind curr_node with
| Cfg.Node.Join_node -> () (* omit join nodes from error traces *)
| Cfg.Node.Start_node pdesc ->
let pname = Cfg.Procdesc.get_proc_name pdesc in
let name = Procname.to_string pname in
let name_id = Procname.to_filename pname in
let descr = "start of procedure " ^ (Procname.to_simplified_string pname) in
let node_tags = [(Io_infer.Xml.tag_kind,"procedure_start"); (Io_infer.Xml.tag_name, name); (Io_infer.Xml.tag_name_id, name_id)] in
trace := mk_trace_elem level curr_loc descr node_tags :: !trace
| Cfg.Node.Prune_node (is_true_branch, if_kind, _) ->
let descr = match is_true_branch, if_kind with
| true, Sil.Ik_if -> "Taking true branch"
| false, Sil.Ik_if -> "Taking false branch"
| true, (Sil.Ik_for | Sil.Ik_while | Sil.Ik_dowhile) -> "Loop condition is true. Entering loop body"
| false, (Sil.Ik_for | Sil.Ik_while | Sil.Ik_dowhile) -> "Loop condition is false. Leaving loop"
| true, Sil.Ik_switch -> "Switch condition is true. Entering switch case"
| false, Sil.Ik_switch -> "Switch condition is false. Skipping switch case"
| true, (Sil.Ik_bexp | Sil.Ik_land_lor) -> "Condition is true"
| false, (Sil.Ik_bexp | Sil.Ik_land_lor) -> "Condition is false" in
let node_tags = [(Io_infer.Xml.tag_kind,"condition"); (Io_infer.Xml.tag_branch, if is_true_branch then "true" else "false")] in
trace := mk_trace_elem level curr_loc descr node_tags :: !trace
| Cfg.Node.Exit_node pdesc ->
let pname = Cfg.Procdesc.get_proc_name pdesc in
let descr = "return from a call to " ^ (Procname.to_string pname) in
let name = Procname.to_string pname in
let name_id = Procname.to_filename pname in
let node_tags = [(Io_infer.Xml.tag_kind,"procedure_end"); (Io_infer.Xml.tag_name, name); (Io_infer.Xml.tag_name_id, name_id)] in
trace := mk_trace_elem level curr_loc descr node_tags :: !trace
| _ ->
let descr, node_tags =
match exn_opt with
| None -> "", []
| Some exn_name ->
let exn_str = Mangled.to_string exn_name in
if exn_str = ""
then "exception", [(Io_infer.Xml.tag_kind,"exception")]
else "exception " ^ exn_str, [(Io_infer.Xml.tag_kind,"exception"); (Io_infer.Xml.tag_name, exn_str)] in
let descr =
match get_description path with
| Some path_descr ->
if String.length descr > 0 then descr^" "^path_descr else path_descr
| None -> descr in
trace := mk_trace_elem level curr_loc descr node_tags :: !trace in
match curr_node path with
| Some curr_node ->
begin
let curr_loc = Cfg.Node.get_loc curr_node in
match Cfg.Node.get_kind curr_node with
| Cfg.Node.Join_node -> () (* omit join nodes from error traces *)
| Cfg.Node.Start_node pdesc ->
let pname = Cfg.Procdesc.get_proc_name pdesc in
let name = Procname.to_string pname in
let name_id = Procname.to_filename pname in
let descr = "start of procedure " ^ (Procname.to_simplified_string pname) in
let node_tags =
[(Io_infer.Xml.tag_kind,"procedure_start");
(Io_infer.Xml.tag_name, name);
(Io_infer.Xml.tag_name_id, name_id)] in
trace := mk_trace_elem level curr_loc descr node_tags :: !trace
| Cfg.Node.Prune_node (is_true_branch, if_kind, _) ->
let descr = match is_true_branch, if_kind with
| true, Sil.Ik_if -> "Taking true branch"
| false, Sil.Ik_if -> "Taking false branch"
| true, (Sil.Ik_for | Sil.Ik_while | Sil.Ik_dowhile) ->
"Loop condition is true. Entering loop body"
| false, (Sil.Ik_for | Sil.Ik_while | Sil.Ik_dowhile) ->
"Loop condition is false. Leaving loop"
| true, Sil.Ik_switch -> "Switch condition is true. Entering switch case"
| false, Sil.Ik_switch -> "Switch condition is false. Skipping switch case"
| true, (Sil.Ik_bexp | Sil.Ik_land_lor) -> "Condition is true"
| false, (Sil.Ik_bexp | Sil.Ik_land_lor) -> "Condition is false" in
let node_tags =
[(Io_infer.Xml.tag_kind,"condition");
(Io_infer.Xml.tag_branch, if is_true_branch then "true" else "false")] in
trace := mk_trace_elem level curr_loc descr node_tags :: !trace
| Cfg.Node.Exit_node pdesc ->
let pname = Cfg.Procdesc.get_proc_name pdesc in
let descr = "return from a call to " ^ (Procname.to_string pname) in
let name = Procname.to_string pname in
let name_id = Procname.to_filename pname in
let node_tags =
[(Io_infer.Xml.tag_kind,"procedure_end");
(Io_infer.Xml.tag_name, name);
(Io_infer.Xml.tag_name_id, name_id)] in
trace := mk_trace_elem level curr_loc descr node_tags :: !trace
| _ ->
let descr, node_tags =
match exn_opt with
| None -> "", []
| Some exn_name ->
let exn_str = Mangled.to_string exn_name in
if exn_str = ""
then "exception", [(Io_infer.Xml.tag_kind,"exception")]
else
"exception " ^ exn_str,
[(Io_infer.Xml.tag_kind,"exception");
(Io_infer.Xml.tag_name, exn_str)] in
let descr =
match get_description path with
| Some path_descr ->
if String.length descr > 0 then descr^" "^path_descr else path_descr
| None -> descr in
trace := mk_trace_elem level curr_loc descr node_tags :: !trace
end
| None ->
() in
iter_longest_sequence g pos_opt path;
let compare lt1 lt2 =
let n = int_compare lt1.Errlog.lt_level lt2.Errlog.lt_level in

@ -31,7 +31,7 @@ module Path : sig
val create_loc_trace : t -> Sil.path_pos option -> Errlog.loc_trace
(** return the current node of the path *)
val curr_node : t -> Cfg.node
val curr_node : t -> Cfg.node option
(** dump a path *)
val d : t -> unit

@ -826,8 +826,12 @@ let normalize_params pdesc prop actual_params =
let prop, args = IList.fold_left norm_arg (prop, []) actual_params in
(prop, IList.rev args)
let do_error_checks node instr pname pdesc =
if !Config.curr_language = Config.Java then PrintfArgs.check_printf_args_ok node instr pname pdesc
let do_error_checks node_opt instr pname pdesc = match node_opt with
| Some node ->
if !Config.curr_language = Config.Java then
PrintfArgs.check_printf_args_ok node instr pname pdesc
| None ->
()
(** Execute [instr] with a symbolic heap [prop].*)
let rec sym_exec cfg tenv pdesc _instr (_prop: Prop.normal Prop.t) path

Loading…
Cancel
Save