[clang] log broken CFGs

Reviewed By: dulmarod

Differential Revision: D7291180

fbshipit-source-id: 93d0024
master
Sam Blackshear 7 years ago committed by Facebook Github Bot
parent 05152e3ade
commit 3e6bd7f063

@ -53,12 +53,11 @@ let iter_all_nodes ?(sorted= false) f cfg =
|> List.iter ~f:(fun (d, n) -> f d n)
(** checks whether a cfg is connected or not *)
let check_cfg_connectedness cfg =
let is_proc_cfg_connected proc_desc =
let is_exit_node n =
match Procdesc.Node.get_kind n with Procdesc.Node.Exit_node _ -> true | _ -> false
in
let broken_node n =
let is_broken_node n =
let succs = Procdesc.Node.get_succs n in
let preds = Procdesc.Node.get_preds n in
match Procdesc.Node.get_kind n with
@ -74,13 +73,7 @@ let check_cfg_connectedness cfg =
(* if the if brances end with a return *)
match succs with [n'] when is_exit_node n' -> false | _ -> Int.equal (List.length preds) 0
in
let do_pdesc pname pd =
let nodes = Procdesc.get_nodes pd in
(* TODO (T20302015): also check the CFGs for the C-like procedures *)
if not Config.keep_going && Typ.Procname.is_java pname && List.exists ~f:broken_node nodes then
L.(die InternalError) "Broken CFG on %a" Typ.Procname.pp pname
in
Typ.Procname.Hash.iter do_pdesc cfg
not (List.exists ~f:is_broken_node (Procdesc.get_nodes proc_desc))
let load_statement =

@ -32,8 +32,8 @@ val create_proc_desc : t -> ProcAttributes.t -> Procdesc.t
val iter_all_nodes : ?sorted:bool -> (Procdesc.t -> Procdesc.Node.t -> unit) -> t -> unit
(** Iterate over all the nodes in the cfg *)
val check_cfg_connectedness : t -> unit
(** checks whether a cfg is connected or not *)
val is_proc_cfg_connected : Procdesc.t -> bool
(** checks whether a cfg for the given procdesc is connected or not *)
val save_attributes : SourceFile.t -> t -> unit
(** Save the .attr files for the procedures in the cfg. *)

@ -21,3 +21,20 @@ let log_caught_exception (trans_unit_ctx: CFrontend_config.translation_unit_cont
; lang= CFrontend_config.string_of_clang_lang trans_unit_ctx.lang }
in
EventLogger.log caught_exception
let log_broken_cfg procdesc exception_triggered_location ~lang =
let proc_location = Procdesc.get_loc procdesc in
let exception_type =
F.asprintf "Broken CFG for %a" Typ.Procname.pp (Procdesc.get_proc_name procdesc)
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

@ -12,3 +12,5 @@ open! IStd
val log_caught_exception :
CFrontend_config.translation_unit_context -> string -> Logging.ocaml_pos
-> Clang_ast_t.source_location * Clang_ast_t.source_location -> string option -> unit
val log_broken_cfg : Procdesc.t -> Logging.ocaml_pos -> lang:string -> unit

@ -53,7 +53,6 @@ let do_source_file (translation_unit_context: CFrontend_config.translation_unit_
NullabilityPreanalysis.analysis cfg tenv ;
SourceFiles.add source_file cfg (FileLocal tenv) ;
if Config.debug_mode then Tenv.store_debug_file_for_source source_file tenv ;
if Config.debug_mode then Cfg.check_cfg_connectedness cfg ;
if Config.debug_mode || Config.testing_mode || Config.frontend_tests
|| Option.is_some Config.icfg_dotty_outfile
then Dotty.print_icfg_dotty source_file cfg ;

@ -84,7 +84,12 @@ module CFrontend_decl_funct (T : CModule_type.CTranslation) : CModule_type.CFron
let proc_attributes = Procdesc.get_attributes procdesc in
Procdesc.Node.add_locals_ret_declaration start_node proc_attributes
(Procdesc.get_locals procdesc) ;
Procdesc.node_set_succs_exn procdesc start_node meth_body_nodes []
Procdesc.node_set_succs_exn procdesc start_node meth_body_nodes [] ;
if not (Cfg.is_proc_cfg_connected procdesc) then
let lang =
CFrontend_config.string_of_clang_lang trans_unit_ctx.CFrontend_config.lang
in
ClangLogging.log_broken_cfg procdesc __POS__ ~lang
| _ ->
()
| exception Not_found ->

Loading…
Cancel
Save