[infer][java] Only create proc_desc for the methods that are defined

Summary: Creating a "fake" procedure description the methods that are called is no longer required by the backend. So this diff cleans up the creation of the procedure descriptions

Reviewed By: jberdine

Differential Revision: D4057185

fbshipit-source-id: b444756
master
Jeremy Dubreil 8 years ago committed by Facebook Github Bot
parent a7d2eb1d02
commit 837cb9b64e

@ -73,47 +73,43 @@ let add_edges
Cfg.Node.set_succs_exn cfg exn_node exit_nodes exit_nodes; Cfg.Node.set_succs_exn cfg exn_node exit_nodes exit_nodes;
Array.iteri connect_nodes method_body_nodes Array.iteri connect_nodes method_body_nodes
(** Add a concrete method. *) (** Add a concrete method. *)
let add_cmethod source_file program icfg cm is_static = let add_cmethod source_file program icfg cm method_kind =
let cfg = icfg.JContext.cfg in let cfg = icfg.JContext.cfg in
let tenv = icfg.JContext.tenv in
let cn, ms = JBasics.cms_split cm.Javalib.cm_class_method_signature in let cn, ms = JBasics.cms_split cm.Javalib.cm_class_method_signature in
match JTrans.get_method_procdesc program cfg tenv cn ms is_static with let proc_name_java = JTransType.get_method_procname cn ms method_kind in
| JTrans.Defined procdesc when JClasspath.is_model (Cfg.Procdesc.get_proc_name procdesc) -> let proc_name = Procname.Java proc_name_java in
(* do not capture the method if there is a model for it *) match Cfg.Procdesc.find_from_name cfg proc_name with
JUtils.log | None -> ()
"Skipping method with a model: %s@." | Some _ when JTrans.is_java_native cm -> ()
(Procname.to_string (Cfg.Procdesc.get_proc_name procdesc)); | Some procdesc ->
| JTrans.Defined procdesc ->
let start_node = Cfg.Procdesc.get_start_node procdesc in let start_node = Cfg.Procdesc.get_start_node procdesc in
let exit_node = Cfg.Procdesc.get_exit_node procdesc in let exit_node = Cfg.Procdesc.get_exit_node procdesc in
let exn_node = let exn_node =
match JContext.get_exn_node procdesc with match JContext.get_exn_node procdesc with
| Some node -> node | Some node -> node
| None -> assert false in | None ->
failwithf "No exn node found for %s" (Procname.to_string proc_name) in
let impl = JTrans.get_implementation cm in let impl = JTrans.get_implementation cm in
let instrs = JBir.code impl in let instrs = JBir.code impl in
let context = let context =
JContext.create_context icfg procdesc impl cn source_file program in JContext.create_context icfg procdesc impl cn source_file program in
let method_body_nodes = Array.mapi (JTrans.instruction context) instrs in let method_body_nodes = Array.mapi (JTrans.instruction context) instrs in
let procname = Cfg.Procdesc.get_proc_name procdesc in
add_edges context start_node exn_node [exit_node] method_body_nodes impl false; add_edges context start_node exn_node [exit_node] method_body_nodes impl false;
Cg.add_defined_node icfg.JContext.cg procname; Cg.add_defined_node icfg.JContext.cg proc_name
| JTrans.Called _ -> ()
(** Add an abstract method. *) (** Add an abstract method. *)
let add_amethod program icfg am is_static = let add_amethod icfg am method_kind =
let cfg = icfg.JContext.cfg in let cfg = icfg.JContext.cfg in
let tenv = icfg.JContext.tenv in
let cn, ms = JBasics.cms_split am.Javalib.am_class_method_signature in let cn, ms = JBasics.cms_split am.Javalib.am_class_method_signature in
match JTrans.get_method_procdesc program cfg tenv cn ms is_static with let proc_name_java = JTransType.get_method_procname cn ms method_kind in
| JTrans.Defined procdesc when (JClasspath.is_model (Cfg.Procdesc.get_proc_name procdesc)) -> let proc_name = Procname.Java proc_name_java in
(* do not capture the method if there is a model for it *) match Cfg.Procdesc.find_from_name cfg proc_name with
JUtils.log "Skipping method with a model: %s@." (Procname.to_string (Cfg.Procdesc.get_proc_name procdesc)); | None -> ()
| JTrans.Defined procdesc -> | Some procdesc ->
Cg.add_defined_node icfg.JContext.cg (Cfg.Procdesc.get_proc_name procdesc) Cg.add_defined_node icfg.JContext.cg (Cfg.Procdesc.get_proc_name procdesc)
| JTrans.Called _ -> ()
let path_of_cached_classname cn = let path_of_cached_classname cn =
@ -155,7 +151,7 @@ let create_icfg source_file linereader program icfg cn node =
let cfg = icfg.JContext.cfg in let cfg = icfg.JContext.cfg in
let tenv = icfg.JContext.tenv in let tenv = icfg.JContext.tenv in
begin begin
Javalib.m_iter (JTrans.create_local_procdesc source_file program linereader cfg tenv) node; Javalib.m_iter (JTrans.create_procdesc source_file program linereader cfg tenv) node;
Javalib.m_iter (fun m -> Javalib.m_iter (fun m ->
(* each procedure has different scope: start names from id 0 *) (* each procedure has different scope: start names from id 0 *)
Ident.NameGenerator.reset (); Ident.NameGenerator.reset ();
@ -164,18 +160,10 @@ let create_icfg source_file linereader program icfg cn node =
| Javalib.ConcreteMethod cm -> | Javalib.ConcreteMethod cm ->
add_cmethod source_file program icfg cm method_kind add_cmethod source_file program icfg cm method_kind
| Javalib.AbstractMethod am -> | Javalib.AbstractMethod am ->
add_amethod program icfg am method_kind add_amethod icfg am method_kind
) node ) node
end end
(*
This type definition is for a future improvement of the capture where in one pass, the frontend will
translate things differently whether a source file is found for a given class
type capture_status =
| With_source of string
| Library of string
| Unknown
*)
(* returns true for the set of classes that are selected to be translated *) (* returns true for the set of classes that are selected to be translated *)
let should_capture classes package_opt source_basename node = let should_capture classes package_opt source_basename node =

@ -206,19 +206,6 @@ type defined_status =
| Defined of Cfg.Procdesc.t | Defined of Cfg.Procdesc.t
| Called of Cfg.Procdesc.t | Called of Cfg.Procdesc.t
type translation_status =
| Created of defined_status
| Unknown
let lookup_procdesc cfg procname =
match Cfg.Procdesc.find_from_name cfg procname with
| Some procdesc ->
if Cfg.Procdesc.is_defined procdesc then
Created (Defined procdesc)
else
Created (Called procdesc)
| None -> Unknown
let is_java_native cm = let is_java_native cm =
(cm.Javalib.cm_implementation = Javalib.Native) (cm.Javalib.cm_implementation = Javalib.Native)
@ -246,11 +233,14 @@ let update_init_loc cn ms loc_start =
with Not_found -> init_loc_map := (JBasics.ClassMap.add cn loc_start !init_loc_map) with Not_found -> init_loc_map := (JBasics.ClassMap.add cn loc_start !init_loc_map)
(** Creates a procedure description. *) (** Creates a procedure description. *)
let create_local_procdesc source_file program linereader cfg tenv m = let create_procdesc source_file program linereader cfg tenv m =
let cn, ms = JBasics.cms_split (Javalib.get_class_method_signature m) in let cn, ms = JBasics.cms_split (Javalib.get_class_method_signature m) in
let proc_name_java = JTransType.get_method_procname cn ms (JTransType.get_method_kind m) in let proc_name_java = JTransType.get_method_procname cn ms (JTransType.get_method_kind m) in
let proc_name = Procname.Java proc_name_java in let proc_name = Procname.Java proc_name_java in
let create_new_procdesc () = if JClasspath.is_model proc_name then
(* do not translate the method if there is a model for it *)
JUtils.log "Skipping method with a model: %s@." (Procname.to_string proc_name)
else
let trans_access = function let trans_access = function
| `Default -> PredSymb.Default | `Default -> PredSymb.Default
| `Public -> PredSymb.Public | `Public -> PredSymb.Public
@ -339,43 +329,8 @@ let create_local_procdesc source_file program linereader cfg tenv m =
Cfg.Node.add_locals_ret_declaration start_node locals; Cfg.Node.add_locals_ret_declaration start_node locals;
with JBir.Subroutine | JBasics.Class_structure_error _ -> with JBir.Subroutine | JBasics.Class_structure_error _ ->
L.err L.err
"create_local_procdesc raised JBir.Subroutine or JBasics.Class_structure_error on %a@." "create_procdesc raised JBir.Subroutine or JBasics.Class_structure_error on %a@."
Procname.pp proc_name in Procname.pp proc_name
match lookup_procdesc cfg proc_name with
| Unknown ->
create_new_procdesc ()
| Created defined_status ->
begin
match defined_status with
| Defined _ -> assert false
| Called procdesc ->
Cfg.Procdesc.remove cfg (Cfg.Procdesc.get_proc_name procdesc) false;
create_new_procdesc ()
end
let create_external_procdesc program cfg tenv cn ms kind =
let return_type =
match JBasics.ms_rtype ms with
| None -> Typ.Tvoid
| Some vt -> JTransType.value_type program tenv vt in
let formals = formals_from_signature program tenv cn ms kind in
let proc_name_java = JTransType.get_method_procname cn ms kind in
ignore (
let proc_attributes =
{ (ProcAttributes.default (Procname.Java proc_name_java) Config.Java) with
ProcAttributes.formals;
ret_type = return_type;
} in
Cfg.Procdesc.create cfg proc_attributes)
(** returns the procedure description of the given method and creates it if it hasn't been created before *)
let rec get_method_procdesc program cfg tenv cn ms kind =
let procname_java = JTransType.get_method_procname cn ms kind in
match lookup_procdesc cfg (Procname.Java procname_java) with
| Unknown ->
create_external_procdesc program cfg tenv cn ms kind;
get_method_procdesc program cfg tenv cn ms kind
| Created status -> status
let builtin_new = let builtin_new =
Exp.Const (Const.Cfun ModelBuiltins.__new) Exp.Const (Const.Cfun ModelBuiltins.__new)

@ -25,12 +25,11 @@ type defined_status =
| Defined of Cfg.Procdesc.t | Defined of Cfg.Procdesc.t
| Called of Cfg.Procdesc.t | Called of Cfg.Procdesc.t
(** returns the procedure description of the given method and creates it if it hasn't been created before *) val is_java_native : JCode.jcode Javalib.concrete_method -> bool
val get_method_procdesc : JClasspath.program -> Cfg.cfg -> Tenv.t -> JBasics.class_name ->
JBasics.method_signature -> Procname.method_kind -> defined_status
(** [create_local_procdesc linereader cfg tenv program m] creates a procedure description for the method m and adds it to cfg *) (** [create_procdesc linereader cfg tenv program m] creates a procedure description
val create_local_procdesc : for the method m and adds it to cfg *)
val create_procdesc :
DB.source_file -> DB.source_file ->
JClasspath.program -> JClasspath.program ->
Printer.LineReader.t -> Printer.LineReader.t ->

@ -186,7 +186,10 @@ let method_signature_names ms =
let args_types = args_to_signature (JBasics.ms_args ms) in let args_types = args_to_signature (JBasics.ms_args ms) in
(return_type_name, method_name, args_types) (return_type_name, method_name, args_types)
let get_method_kind m = if Javalib.is_static_method m then Procname.Static else Procname.Non_Static let get_method_kind m =
if Javalib.is_static_method m
then Procname.Static
else Procname.Non_Static
(* create a mangled procname from an abstract or concrete method *) (* create a mangled procname from an abstract or concrete method *)
let get_method_procname cn ms kind = let get_method_procname cn ms kind =

Loading…
Cancel
Save