diff --git a/infer/src/IR/Cfg.ml b/infer/src/IR/Cfg.ml index 708f2549f..ca6c80455 100644 --- a/infer/src/IR/Cfg.ml +++ b/infer/src/IR/Cfg.ml @@ -31,7 +31,6 @@ let get_all_defined_proc_names cfg = !procs -(** Create a new procdesc *) let create_proc_desc cfg (proc_attributes : ProcAttributes.t) = let pdesc = Procdesc.from_proc_attributes proc_attributes in let pname = proc_attributes.proc_name in diff --git a/infer/src/IR/Cfg.mli b/infer/src/IR/Cfg.mli index 95a88e71f..5f0aa2534 100644 --- a/infer/src/IR/Cfg.mli +++ b/infer/src/IR/Cfg.mli @@ -28,7 +28,8 @@ val create : unit -> t (** create a new empty cfg *) val create_proc_desc : t -> ProcAttributes.t -> Procdesc.t -(** Create a new procdesc and add it to the cfg *) +(** Create a new procdesc. If the procedure is defined, you need to create and set the start/exit + nodes after creating the procedure. *) val iter_sorted : t -> f:(Procdesc.t -> unit) -> unit (** Iterate over all the proc descs in the cfg in ascending order *) diff --git a/infer/src/IR/Io_infer.ml b/infer/src/IR/Io_infer.ml index 7377fe1b4..a2135adb0 100644 --- a/infer/src/IR/Io_infer.ml +++ b/infer/src/IR/Io_infer.ml @@ -11,11 +11,14 @@ open! IStd (** Module to handle IO. Includes html and xml modules. *) module F = Format +module L = Logging (* =============== START of module Html =============== *) module Html = struct (** Create a new html file *) let create source path = + if SourceFile.is_invalid source then + L.debug Capture Verbose "Invalid source. (Did you forget to create a start/exit node?)" ; let fname, dir_path = match List.rev path with | fname :: path_rev -> diff --git a/infer/src/IR/Procdesc.mli b/infer/src/IR/Procdesc.mli index 0575165bb..475e6fa75 100644 --- a/infer/src/IR/Procdesc.mli +++ b/infer/src/IR/Procdesc.mli @@ -260,6 +260,7 @@ val get_locals : t -> ProcAttributes.var_data list (** Return name and type and attributes of local variables *) val get_nodes : t -> Node.t list +(** Return the nodes, excluding the start node and the exit node. *) val get_proc_name : t -> Procname.t diff --git a/infer/src/IR/Procname.ml b/infer/src/IR/Procname.ml index bdda4d265..7909bc5c2 100644 --- a/infer/src/IR/Procname.ml +++ b/infer/src/IR/Procname.ml @@ -467,14 +467,18 @@ end module Erlang = struct type t = {module_name: string; function_name: string; arity: int} [@@deriving compare, yojson_of] - let pp verbosity fmt {module_name; function_name; arity} = + let pp_general arity_sep verbosity fmt {module_name; function_name; arity} = match verbosity with | Simple | Non_verbose -> - F.fprintf fmt "%s/%d" function_name arity + F.fprintf fmt "%s%c%d" function_name arity_sep arity | Verbose -> - F.fprintf fmt "%s:%s/%d" module_name function_name arity + F.fprintf fmt "%s:%s%c%d" module_name function_name arity_sep arity + let pp verbosity fmt pname = pp_general '/' verbosity fmt pname + + let pp_filename fmt pname = pp_general '#' Verbose fmt pname + let set_arity arity name = {name with arity} end @@ -1084,6 +1088,8 @@ let to_filename pname = let pp_mangled fmt = function None -> () | Some mangled -> F.fprintf fmt "#%s" mangled in F.asprintf "%a%a%a" pp_rev_qualified pname Parameter.pp_parameters parameters pp_mangled mangled + | Erlang pname -> + F.asprintf "%a" Erlang.pp_filename pname | ObjC_Cpp objc_cpp -> F.asprintf "%a%a#%a" pp_rev_qualified pname Parameter.pp_parameters objc_cpp.parameters ObjC_Cpp.pp_verbose_kind objc_cpp.kind diff --git a/infer/src/backend/registerCheckers.ml b/infer/src/backend/registerCheckers.ml index 167853467..3a06a4023 100644 --- a/infer/src/backend/registerCheckers.ml +++ b/infer/src/backend/registerCheckers.ml @@ -155,7 +155,7 @@ let all_checkers = ; { checker= Pulse ; callbacks= (let pulse = interprocedural Payloads.Fields.pulse Pulse.checker in - [(pulse, Clang); (pulse, Java)] ) } + [(pulse, Clang); (pulse, Erlang); (pulse, Java)] ) } ; { checker= Impurity ; callbacks= (let impurity = diff --git a/infer/src/erlang/ErlangTranslator.ml b/infer/src/erlang/ErlangTranslator.ml index b63abe5f8..32ae0c836 100644 --- a/infer/src/erlang/ErlangTranslator.ml +++ b/infer/src/erlang/ErlangTranslator.ml @@ -388,9 +388,16 @@ let translate_one_function env cfg function_ clauses = let default = ProcAttributes.default env.location.file name in let access : ProcAttributes.access = if Set.mem env.exports uf_name then Public else Private in let formals = List.init ~f:(fun i -> (mangled_arg i, any)) arity in - {default with access; formals; loc= env.location; ret_type= any} + {default with access; formals; is_defined= true; loc= env.location; ret_type= any} + in + let procdesc = + let procdesc = Cfg.create_proc_desc cfg attributes in + let start_node = Procdesc.create_node procdesc env.location Start_node [] in + let exit_node = Procdesc.create_node procdesc env.location Exit_node [] in + Procdesc.set_start_node procdesc start_node ; + Procdesc.set_exit_node procdesc exit_node ; + procdesc in - let procdesc = Cfg.create_proc_desc cfg attributes in let env = {env with procdesc= Some procdesc; result= Some (Exp.Lvar (Pvar.get_ret_pvar name))} in let idents, loads = let load (formal, typ) = @@ -436,8 +443,8 @@ let translate_functions env cfg module_ = in List.iter module_ ~f ; DB.Results_dir.init env.location.file ; - Cfg.store env.location.file cfg ; - SourceFiles.add env.location.file cfg Tenv.Global None + let tenv = Tenv.FileLocal (Tenv.create ()) in + SourceFiles.add env.location.file cfg tenv None let translate_module module_ =