From 837cb9b64e1edd07ded86802e4c2dc9ce09f324c Mon Sep 17 00:00:00 2001 From: Jeremy Dubreil Date: Fri, 21 Oct 2016 08:42:59 -0700 Subject: [PATCH] [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 --- infer/src/java/jFrontend.ml | 50 ++++++++++++------------------ infer/src/java/jTrans.ml | 59 +++++------------------------------- infer/src/java/jTrans.mli | 9 +++--- infer/src/java/jTransType.ml | 5 ++- 4 files changed, 34 insertions(+), 89 deletions(-) diff --git a/infer/src/java/jFrontend.ml b/infer/src/java/jFrontend.ml index 5df456c6f..097b94cea 100644 --- a/infer/src/java/jFrontend.ml +++ b/infer/src/java/jFrontend.ml @@ -73,47 +73,43 @@ let add_edges Cfg.Node.set_succs_exn cfg exn_node exit_nodes exit_nodes; Array.iteri connect_nodes method_body_nodes + (** 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 tenv = icfg.JContext.tenv 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 - | JTrans.Defined procdesc when JClasspath.is_model (Cfg.Procdesc.get_proc_name procdesc) -> - (* do not capture the method if there is a model for it *) - JUtils.log - "Skipping method with a model: %s@." - (Procname.to_string (Cfg.Procdesc.get_proc_name procdesc)); - | JTrans.Defined procdesc -> + let proc_name_java = JTransType.get_method_procname cn ms method_kind in + let proc_name = Procname.Java proc_name_java in + match Cfg.Procdesc.find_from_name cfg proc_name with + | None -> () + | Some _ when JTrans.is_java_native cm -> () + | Some procdesc -> let start_node = Cfg.Procdesc.get_start_node procdesc in let exit_node = Cfg.Procdesc.get_exit_node procdesc in let exn_node = match JContext.get_exn_node procdesc with | 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 instrs = JBir.code impl in let context = JContext.create_context icfg procdesc impl cn source_file program 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; - Cg.add_defined_node icfg.JContext.cg procname; - | JTrans.Called _ -> () + Cg.add_defined_node icfg.JContext.cg proc_name (** 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 tenv = icfg.JContext.tenv 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 - | JTrans.Defined procdesc when (JClasspath.is_model (Cfg.Procdesc.get_proc_name procdesc)) -> - (* do not capture the method if there is a model for it *) - JUtils.log "Skipping method with a model: %s@." (Procname.to_string (Cfg.Procdesc.get_proc_name procdesc)); - | JTrans.Defined procdesc -> + let proc_name_java = JTransType.get_method_procname cn ms method_kind in + let proc_name = Procname.Java proc_name_java in + match Cfg.Procdesc.find_from_name cfg proc_name with + | None -> () + | Some procdesc -> Cg.add_defined_node icfg.JContext.cg (Cfg.Procdesc.get_proc_name procdesc) - | JTrans.Called _ -> () 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 tenv = icfg.JContext.tenv in 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 -> (* each procedure has different scope: start names from id 0 *) Ident.NameGenerator.reset (); @@ -164,18 +160,10 @@ let create_icfg source_file linereader program icfg cn node = | Javalib.ConcreteMethod cm -> add_cmethod source_file program icfg cm method_kind | Javalib.AbstractMethod am -> - add_amethod program icfg am method_kind + add_amethod icfg am method_kind ) node 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 *) let should_capture classes package_opt source_basename node = diff --git a/infer/src/java/jTrans.ml b/infer/src/java/jTrans.ml index 934fe86dc..cc2058b22 100644 --- a/infer/src/java/jTrans.ml +++ b/infer/src/java/jTrans.ml @@ -206,19 +206,6 @@ type defined_status = | Defined 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 = (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) (** 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 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 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 | `Default -> PredSymb.Default | `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; with JBir.Subroutine | JBasics.Class_structure_error _ -> L.err - "create_local_procdesc raised JBir.Subroutine or JBasics.Class_structure_error on %a@." - Procname.pp proc_name in - 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 + "create_procdesc raised JBir.Subroutine or JBasics.Class_structure_error on %a@." + Procname.pp proc_name let builtin_new = Exp.Const (Const.Cfun ModelBuiltins.__new) diff --git a/infer/src/java/jTrans.mli b/infer/src/java/jTrans.mli index deb857ed5..6818938a4 100644 --- a/infer/src/java/jTrans.mli +++ b/infer/src/java/jTrans.mli @@ -25,12 +25,11 @@ type defined_status = | Defined 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 get_method_procdesc : JClasspath.program -> Cfg.cfg -> Tenv.t -> JBasics.class_name -> - JBasics.method_signature -> Procname.method_kind -> defined_status +val is_java_native : JCode.jcode Javalib.concrete_method -> bool -(** [create_local_procdesc linereader cfg tenv program m] creates a procedure description for the method m and adds it to cfg *) -val create_local_procdesc : +(** [create_procdesc linereader cfg tenv program m] creates a procedure description + for the method m and adds it to cfg *) +val create_procdesc : DB.source_file -> JClasspath.program -> Printer.LineReader.t -> diff --git a/infer/src/java/jTransType.ml b/infer/src/java/jTransType.ml index 91f6187bd..7724f49ef 100644 --- a/infer/src/java/jTransType.ml +++ b/infer/src/java/jTransType.ml @@ -186,7 +186,10 @@ let method_signature_names ms = let args_types = args_to_signature (JBasics.ms_args ms) in (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 *) let get_method_procname cn ms kind =