From 9157f42b7c478375ecdccc27d72b3068f47a1996 Mon Sep 17 00:00:00 2001 From: Sam Blackshear Date: Tue, 9 May 2017 10:31:43 -0700 Subject: [PATCH] [test] diagnose invalid source file issue Reviewed By: jvillard Differential Revision: D4984324 fbshipit-source-id: 2b1f678 --- infer/src/IR/Errlog.ml | 6 ++++++ infer/src/IR/Errlog.mli | 4 ++++ infer/src/IR/Location.re | 5 +---- infer/src/IR/ProcAttributes.re | 2 +- infer/src/backend/InferPrint.re | 10 ++++++++++ infer/src/backend/exe_env.ml | 2 +- infer/src/base/SourceFile.ml | 18 +++++++++++------- infer/src/base/SourceFile.mli | 2 +- infer/src/quandary/TaintAnalysis.ml | 3 ++- 9 files changed, 37 insertions(+), 15 deletions(-) diff --git a/infer/src/IR/Errlog.ml b/infer/src/IR/Errlog.ml index ca5615740..d3c8ceefb 100644 --- a/infer/src/IR/Errlog.ml +++ b/infer/src/IR/Errlog.ml @@ -27,6 +27,12 @@ type loc_trace_elem = { lt_node_tags : node_tag list (** tags describing the node at the current location *) } +let pp_loc_trace_elem fmt { lt_level; lt_loc; } = + F.fprintf fmt "%d %a" lt_level Location.pp lt_loc + +let pp_loc_trace fmt l = + PrettyPrintable.pp_collection ~pp_item:pp_loc_trace_elem fmt l + let contains_exception loc_trace_elem = let pred nt = match nt with diff --git a/infer/src/IR/Errlog.mli b/infer/src/IR/Errlog.mli index d60e35f55..b9245bbe4 100644 --- a/infer/src/IR/Errlog.mli +++ b/infer/src/IR/Errlog.mli @@ -74,6 +74,10 @@ type iter_fun = err_key -> err_data -> unit (** Apply f to nodes and error names *) val iter : iter_fun -> t -> unit +val pp_loc_trace_elem : Format.formatter -> loc_trace_elem -> unit + +val pp_loc_trace : Format.formatter -> loc_trace -> unit + (** Print errors from error log *) val pp_errors : Format.formatter -> t -> unit diff --git a/infer/src/IR/Location.re b/infer/src/IR/Location.re index c03732a2a..32b811184 100644 --- a/infer/src/IR/Location.re +++ b/infer/src/IR/Location.re @@ -29,10 +29,7 @@ let d (loc: t) => L.add_print_action (L.PTloc, Obj.repr loc); let none file => {line: (-1), col: (-1), file}; - -/** Dummy location */ -let dummy = none SourceFile.invalid; - +let dummy = none (SourceFile.invalid __FILE__); /** Pretty print a location */ let pp f (loc: t) => F.fprintf f "[line %d]" loc.line; diff --git a/infer/src/IR/ProcAttributes.re b/infer/src/IR/ProcAttributes.re index 625566850..eb5c3166f 100644 --- a/infer/src/IR/ProcAttributes.re +++ b/infer/src/IR/ProcAttributes.re @@ -100,5 +100,5 @@ let default proc_name language => { proc_flags: proc_flags_empty (), proc_name, ret_type: Typ.mk Typ.Tvoid, - source_file_captured: SourceFile.invalid + source_file_captured: SourceFile.invalid __FILE__ }; diff --git a/infer/src/backend/InferPrint.re b/infer/src/backend/InferPrint.re index c0f82e156..fe65d6a1f 100644 --- a/infer/src/backend/InferPrint.re +++ b/infer/src/backend/InferPrint.re @@ -442,6 +442,16 @@ module IssuesJson = { | Some proc_loc => (proc_loc.Location.file, proc_loc.Location.line) | None => (err_data.loc.Location.file, 0) }; + if (SourceFile.is_invalid source_file) { + failwithf + "Invalid source file for %a %a@.Trace: %a@." + Localise.pp + key.err_name + Localise.pp_error_desc + key.err_desc + Errlog.pp_loc_trace + err_data.loc_trace + }; let should_report_source_file = not (SourceFile.is_infer_model source_file) || Config.debug_mode || Config.debug_exceptions; diff --git a/infer/src/backend/exe_env.ml b/infer/src/backend/exe_env.ml index 6d0defb70..3c9f7e206 100644 --- a/infer/src/backend/exe_env.ml +++ b/infer/src/backend/exe_env.ml @@ -75,7 +75,7 @@ type initial = t (** create a new execution environment *) let create () = - { cg = Cg.create SourceFile.invalid; + { cg = Cg.create (SourceFile.invalid __FILE__); proc_map = Typ.Procname.Hash.create 17; file_map = FilenameHash.create 1; source_files = SourceFile.Set.empty; diff --git a/infer/src/base/SourceFile.ml b/infer/src/base/SourceFile.ml index 2bedb4f47..298c845e1 100644 --- a/infer/src/base/SourceFile.ml +++ b/infer/src/base/SourceFile.ml @@ -15,7 +15,7 @@ let count_newlines (path: string): int = In_channel.with_file path ~f type t = - | Invalid + | Invalid of string (* ML function of origin *) | Absolute of string | RelativeProjectRoot of string (* relative to project root *) | RelativeInferModel of string (* relative to infer models *) @@ -54,7 +54,7 @@ let from_abs_path fname = let to_string fname = match fname with - | Invalid -> "DUMMY" + | Invalid origin -> "DUMMY from " ^ origin | RelativeInferModel path -> "INFER_MODEL/" ^ path | RelativeProjectRoot path | Absolute path -> path @@ -65,7 +65,8 @@ let pp fmt fname = (* Checking if the path exists may be needed only in some cases, hence the flag check_exists *) let to_abs_path fname = match fname with - | Invalid -> invalid_arg "cannot be called with Invalid source file" + | Invalid origin -> + invalid_arg ("cannot be called with Invalid source file originating in " ^ origin) | RelativeProjectRoot path -> Filename.concat Config.project_root path | RelativeInferModel path -> Filename.concat Config.models_src_dir path | Absolute path -> path @@ -79,12 +80,15 @@ let to_rel_path fname = | RelativeProjectRoot path -> path | _ -> to_abs_path fname -let invalid = Invalid +let invalid origin = Invalid origin + +let is_invalid = function + | Invalid _ -> true + | _ -> false -let is_invalid = equal Invalid let is_infer_model source_file = match source_file with - | Invalid -> invalid_arg "cannot be called with Invalid source file" + | Invalid origin -> invalid_arg ("cannot be called with Invalid source file from " ^ origin) | RelativeProjectRoot _ | Absolute _ -> false | RelativeInferModel _ -> true @@ -96,7 +100,7 @@ let is_cpp_model file = | _ -> false let is_under_project_root = function - | Invalid -> invalid_arg "cannot be called with Invalid source file" + | Invalid origin -> invalid_arg ("cannot be called with Invalid source file from " ^ origin) | RelativeProjectRoot _ -> true | Absolute _ | RelativeInferModel _ -> false diff --git a/infer/src/base/SourceFile.mli b/infer/src/base/SourceFile.mli index 051876137..eb21d2f30 100644 --- a/infer/src/base/SourceFile.mli +++ b/infer/src/base/SourceFile.mli @@ -31,7 +31,7 @@ val is_invalid : t -> bool val changed_files_set : Set.t option (** Invalid source file *) -val invalid : t +val invalid : string -> t (** equality of source files *) val equal : t -> t -> bool diff --git a/infer/src/quandary/TaintAnalysis.ml b/infer/src/quandary/TaintAnalysis.ml index e2fe0f1c4..29f84ff37 100644 --- a/infer/src/quandary/TaintAnalysis.ml +++ b/infer/src/quandary/TaintAnalysis.ml @@ -536,7 +536,8 @@ module Make (TaintSpecification : TaintSpec.S) = struct then begin Preanal.do_liveness proc_data.pdesc proc_data.tenv; - Preanal.do_dynamic_dispatch proc_data.pdesc (Cg.create SourceFile.invalid) proc_data.tenv; + Preanal.do_dynamic_dispatch + proc_data.pdesc (Cg.create (SourceFile.invalid __FILE__)) proc_data.tenv; end; let initial = make_initial proc_data.pdesc in match Analyzer.compute_post proc_data ~initial with