[debt] delete Procdesc.is_connected

Summary:
At some point we thought disconnected CFGs (where some nodes are not
reachable from the initial node) were signs of bugs in our frontend, but
it turned out not to be the case. Thus, we compute the boolean "is
connected" for each procdesc for the only purpose of logging that
uninteresting piece of information.

Delete it.

Reviewed By: ngorogiannis

Differential Revision: D20342834

fbshipit-source-id: 3f9317003
master
Jules Villard 5 years ago committed by Facebook Github Bot
parent 8e5ee67fed
commit 6e1cca731c

@ -795,70 +795,6 @@ let has_modify_in_block_attr procdesc pvar =
List.exists ~f:pvar_local_matches (get_locals procdesc)
let is_connected proc_desc =
let is_exit_node n = match Node.get_kind n with Node.Exit_node -> true | _ -> false in
let is_between_join_and_exit_node n =
match Node.get_kind n with
| Node.Stmt_node (BetweenJoinAndExit | Destruction _) -> (
match Node.get_succs n with [n'] when is_exit_node n' -> true | _ -> false )
| _ ->
false
in
let rec is_consecutive_join_nodes n visited =
match Node.get_kind n with
| Node.Join_node -> (
if NodeSet.mem n visited then false
else
let succs = Node.get_succs n in
match succs with
| [n'] ->
is_consecutive_join_nodes n' (NodeSet.add n visited)
| _ ->
false )
| _ ->
is_between_join_and_exit_node n
in
let find_broken_node n =
let succs = Node.get_succs n in
let preds = Node.get_preds n in
match Node.get_kind n with
| Node.Start_node ->
if List.is_empty succs || not (List.is_empty preds) then Error `Other else Ok ()
| Node.Exit_node ->
if (not (List.is_empty succs)) || List.is_empty preds then Error `Other else Ok ()
| Node.Stmt_node _ | Node.Prune_node _ | Node.Skip_node _ ->
if List.is_empty succs || List.is_empty preds then Error `Other else Ok ()
| Node.Join_node ->
(* Join node has the exception that it may be without predecessors
and pointing to between_join_and_exit which points to an exit node.
This happens when the if branches end with a return.
Nested if statements, where all branches have return statements,
introduce a sequence of join nodes *)
if
(List.is_empty preds && not (is_consecutive_join_nodes n NodeSet.empty))
|| ((not (List.is_empty preds)) && List.is_empty succs)
then Error `Join
else Ok ()
in
(* unconnected nodes generated by Join nodes are expected *)
let skip_join_errors current_status node =
match find_broken_node node with
| Ok () ->
Ok current_status
| Error `Join ->
Ok (Some `Join)
| Error _ as other_error ->
other_error
in
match List.fold_result (get_nodes proc_desc) ~init:None ~f:skip_join_errors with
| Ok (Some `Join) ->
Error `Join
| Ok None ->
Ok ()
| Error _ as error ->
error
module SQLite = SqliteUtils.MarshalledNullableDataNOTForComparison (struct
type nonrec t = t
end)

@ -312,9 +312,6 @@ val is_captured_var : t -> Var.t -> bool
val has_modify_in_block_attr : t -> Pvar.t -> bool
val is_connected : t -> (unit, [`Join | `Other]) Result.t
(** checks whether a cfg for the given procdesc is connected or not *)
module SQLite : SqliteUtils.Data with type t = t option
(** per-procedure CFGs are stored in the SQLite "procedures" table as NULL if the procedure has no
CFG *)

@ -32,20 +32,3 @@ let log_caught_exception trans_unit_ctx exception_type exception_triggered_locat
let log_unexpected_decl trans_unit_ctx exception_triggered_location source_range ast_node =
log_frontend_exception trans_unit_ctx "Skipped declaration inside a class"
exception_triggered_location source_range ast_node
let log_broken_cfg ~broken_node procdesc exception_triggered_location ~lang =
let proc_location = Procdesc.get_loc procdesc in
let exception_type =
match broken_node with `Other -> "Broken CFG" | `Join -> "Broken CFG at join node"
in
let cfg_exception =
EventLogger.FrontendException
{ source_location_start= proc_location
; source_location_end= proc_location
; ast_node= None
; exception_triggered_location
; exception_type
; lang }
in
EventLogger.log cfg_exception

@ -15,9 +15,6 @@ val log_caught_exception :
-> string option
-> unit
val log_broken_cfg :
broken_node:[`Join | `Other] -> Procdesc.t -> Logging.ocaml_pos -> lang:string -> unit
val log_unexpected_decl :
CFrontend_config.translation_unit_context
-> Logging.ocaml_pos

@ -34,8 +34,8 @@ module CFrontend_decl_funct (T : CModule_type.CTranslation) : CModule_type.CFron
SourceFile.pp trans_unit_ctx.CFrontend_config.source_file
in
let f () =
match Procname.Hash.find cfg procname with
| procdesc when Procdesc.is_defined procdesc && not (model_exists procname) -> (
match Procname.Hash.find_opt cfg procname with
| Some procdesc when Procdesc.is_defined procdesc && not (model_exists procname) ->
L.(debug Capture Verbose)
"@\n@\n>>---------- Start translating body of function: '%s' ---------<<@\n@."
(Procname.to_string procname) ;
@ -49,19 +49,9 @@ module CFrontend_decl_funct (T : CModule_type.CTranslation) : CModule_type.CFron
let meth_body_nodes =
T.instructions_trans context body extra_instrs exit_node ~is_destructor_wrapper
in
Procdesc.node_set_succs procdesc start_node ~normal:meth_body_nodes ~exn:[] ;
match Procdesc.is_connected procdesc with
| Ok () ->
()
| Error broken_node ->
let lang =
CFrontend_config.string_of_clang_lang trans_unit_ctx.CFrontend_config.lang
in
ClangLogging.log_broken_cfg ~broken_node procdesc __POS__ ~lang )
Procdesc.node_set_succs procdesc start_node ~normal:meth_body_nodes ~exn:[]
| _ ->
()
| exception Caml.Not_found ->
()
in
CFrontend_errors.protect ~f ~recover ~pp_context trans_unit_ctx

Loading…
Cancel
Save