From 588142c908b91c7fdbd1d990a3f3c6e746b00afd Mon Sep 17 00:00:00 2001 From: Jules Villard Date: Wed, 18 Oct 2017 08:19:25 -0700 Subject: [PATCH] [checkers] enable biabduction by default + docs and logs improvements Summary: Refactor `RegisterCheckers` to give a record type to checkers instead of a tuple type. Print active checkers with their per-language information. Improve the manual entries slightly. Reviewed By: sblackshear Differential Revision: D6051167 fbshipit-source-id: 90bcb61 --- infer/src/backend/DifferentialFilters.ml | 5 +- infer/src/backend/InferAnalyze.ml | 22 ++- infer/src/backend/infer.ml | 16 +- infer/src/base/Config.ml | 87 +++++----- infer/src/base/Config.mli | 2 + infer/src/checkers/registerCheckers.ml | 149 +++++++++++------- infer/src/checkers/registerCheckers.mli | 8 +- infer/tests/build_systems/gradle/Makefile | 2 +- .../resource_leak_exception_lines/Makefile | 4 +- .../codetoanalyze/cpp/threadsafety/Makefile | 2 +- infer/tests/codetoanalyze/cpp/uninit/Makefile | 2 +- .../java/crashcontext/issues.exp | 10 +- 12 files changed, 192 insertions(+), 117 deletions(-) diff --git a/infer/src/backend/DifferentialFilters.ml b/infer/src/backend/DifferentialFilters.ml index 1419de1e1..0b8e00de8 100644 --- a/infer/src/backend/DifferentialFilters.ml +++ b/infer/src/backend/DifferentialFilters.ml @@ -252,10 +252,7 @@ let do_filter (diff: Differential.t) (renamings: FileRenamings.t) ~(skip_duplica else issues in let diff' = - diff - |> ( if Config.equal_analyzer Config.analyzer Config.BiAbduction then - skip_anonymous_class_renamings - else Fn.id ) + diff |> (if Config.biabduction then skip_anonymous_class_renamings else Fn.id) |> (if skip_duplicated_types then skip_duplicated_types_on_filenames renamings else Fn.id) |> Fn.id in diff --git a/infer/src/backend/InferAnalyze.ml b/infer/src/backend/InferAnalyze.ml index d87f6dad8..4e8fc6b35 100644 --- a/infer/src/backend/InferAnalyze.ml +++ b/infer/src/backend/InferAnalyze.ml @@ -112,14 +112,21 @@ let cluster_should_be_analyzed ~changed_files cluster = | None -> true +let register_active_checkers () = + match Config.analyzer with + | Checkers | Crashcontext + -> RegisterCheckers.get_active_checkers () |> RegisterCheckers.register + | BiAbduction | CaptureOnly | CompileOnly | Linters + -> () + let main ~changed_files ~makefile = BuiltinDefn.init () ; - RegisterCheckers.register () ; ( match Config.modified_targets with | Some file -> MergeCapture.record_modified_targets_from_file file | None -> () ) ; + register_active_checkers () ; match Config.cluster_cmdline with | Some fname -> process_cluster_cmdline fname @@ -136,17 +143,16 @@ let main ~changed_files ~makefile = else "" ) (if Int.equal n_clusters_to_analyze 1 then "" else "s") Config.results_dir ; - let is_java () = - List.exists - ~f:(fun cl -> DB.string_crc_has_extension ~ext:"java" (DB.source_dir_to_string cl)) - all_clusters + let is_java = + ( lazy + (List.exists + ~f:(fun cl -> DB.string_crc_has_extension ~ext:"java" (DB.source_dir_to_string cl)) + all_clusters) ) in - (if Config.print_active_checkers then L.result else L.debug Analysis Quiet) - "Active checkers: %a@\n" RegisterCheckers.pp_active_checkers () ; L.debug Analysis Quiet "Dynamic dispatch mode: %s@." Config.(string_of_dynamic_dispatch dynamic_dispatch) ; print_legend () ; - if Config.per_procedure_parallelism && not (is_java ()) then ( + if Config.per_procedure_parallelism && not (Lazy.force is_java) then ( (* Java uses ZipLib which is incompatible with forking *) (* per-procedure parallelism *) L.environment_info "Per-procedure parallelism jobs: %d@." Config.jobs ; diff --git a/infer/src/backend/infer.ml b/infer/src/backend/infer.ml index 181d5f749..9b39ea955 100644 --- a/infer/src/backend/infer.ml +++ b/infer/src/backend/infer.ml @@ -43,15 +43,29 @@ let setup () = | Explore -> ResultsDir.assert_results_dir "please run an infer analysis first" +let print_active_checkers () = + (if Config.print_active_checkers && CLOpt.is_originator then L.result else L.environment_info) + "Analyzer: %s@." + Config.(string_of_analyzer analyzer) ; + (if Config.print_active_checkers && CLOpt.is_originator then L.result else L.environment_info) + "Active checkers: %a@." (Pp.seq ~sep:", " RegisterCheckers.pp_checker) + (RegisterCheckers.get_active_checkers ()) + let log_environment_info () = L.environment_info "CWD = %s@\n" (Sys.getcwd ()) ; + ( match Config.inferconfig_file with + | Some file + -> L.environment_info "Read configuration in %s@\n" file + | None + -> L.environment_info "No .inferconfig file found@\n" ) ; L.environment_info "Project root = %s@\n" Config.project_root ; let infer_args = Sys.getenv CLOpt.args_env_var |> Option.map ~f:(String.split ~on:CLOpt.env_var_sep) |> Option.value ~default:[""] in L.environment_info "INFER_ARGS = %a" Pp.cli_args infer_args ; - L.environment_info "command line arguments: %a" Pp.cli_args (Array.to_list Sys.argv) + L.environment_info "command line arguments: %a" Pp.cli_args (Array.to_list Sys.argv) ; + print_active_checkers () let () = ( if Config.linters_validate_syntax_only then diff --git a/infer/src/base/Config.ml b/infer/src/base/Config.ml index 1113cd163..8cb4ce651 100644 --- a/infer/src/base/Config.ml +++ b/infer/src/base/Config.ml @@ -529,6 +529,10 @@ let exe_usage = let anon_args = CLOpt.mk_anon () +let all_checkers = ref [] + +let disable_all_checkers () = List.iter !all_checkers ~f:(fun (var, _, _, _) -> var := false) + let () = let on_unknown_arg_from_command (cmd: CLOpt.command) = match cmd with @@ -662,19 +666,16 @@ and ( annotation_reachability , threadsafety , suggest_nullable , uninit ) = - let all_checkers = ref [] in - let default_checkers = ref [] in let mk_checker ?(default= false) ~long doc = let var = CLOpt.mk_bool ~long ~in_help:CLOpt.([(Analyze, manual_generic)]) ~default doc in - all_checkers := (var, long) :: !all_checkers ; - if default then default_checkers := (var, long) :: !default_checkers ; + all_checkers := (var, long, doc, default) :: !all_checkers ; var in let annotation_reachability = mk_checker ~default:true ~long:"annotation-reachability" "the annotation reachability checker. Given a pair of source and sink annotation, e.g. @PerformanceCritical and @Expensive, this checker will warn whenever some method annotated with @PerformanceCritical calls, directly or indirectly, another method annotated with @Expensive" and biabduction = - mk_checker ~long:"biabduction" + mk_checker ~long:"biabduction" ~default:true "the separation logic based bi-abduction analysis using the checkers framework" and bufferoverrun = mk_checker ~long:"bufferoverrun" "the buffer overrun analysis" and check_nullable = @@ -696,27 +697,29 @@ and ( annotation_reachability and printf_args = mk_checker ~long:"printf-args" ~default:true "the detection of mismatch between the Java printf format strings and the argument types For, example, this checker will warn about the type error in `printf(\"Hello %d\", \"world\")`" - and repeated_calls = mk_checker ~long:"repeated-calls" "check for repeated calls" and quandary = mk_checker ~long:"quandary" ~default:true "the quandary taint analysis" + and repeated_calls = mk_checker ~long:"repeated-calls" "check for repeated calls" and resource_leak = mk_checker ~long:"resource-leak" "" and siof = mk_checker ~long:"siof" ~default:true "the Static Initialization Order Fiasco analysis (C++ only)" - and threadsafety = mk_checker ~long:"threadsafety" ~default:true "the thread safety analysis" and suggest_nullable = - mk_checker ~long:"suggest-nullable" ~default:false - "Nullable annotation sugesstions analysis (experimental)" + mk_checker ~long:"suggest-nullable" ~default:false "Nullable annotation sugesstions analysis" + and threadsafety = mk_checker ~long:"threadsafety" ~default:true "the thread safety analysis" and uninit = mk_checker ~long:"uninit" ~default:true "checker for use of uninitialized values" in - let mk_only (var, long) = + let mk_only (var, long, doc, _) = let _ : bool ref = CLOpt.mk_bool_group ~long:(long ^ "-only") ~in_help:CLOpt.([(Analyze, manual_generic)]) - (Printf.sprintf "Enable $(b,--%s) and disable all other checkers" long) - [(* enable this checker *) var] - ((* disable all checkers except this one *) - List.filter_map - ~f:(fun (var', long') -> if String.equal long long' then None else Some var') - !all_checkers) + ~f:(fun b -> + disable_all_checkers () ; + var := b ; + b) + ( if String.equal doc "" then "" + else Printf.sprintf "Enable $(b,--%s) and disable all other checkers" long ) + [] (* do all the work in ~f *) + [] + (* do all the work in ~f *) in () in @@ -726,10 +729,20 @@ and ( annotation_reachability ~in_help:CLOpt.([(Analyze, manual_generic)]) ~default:true ( "Default checkers: " - ^ ( List.map ~f:(fun (_, s) -> Printf.sprintf "$(b,--%s)" s) !default_checkers + ^ ( List.rev_filter_map + ~f:(fun (_, long, _, default) -> + if default then Some (Printf.sprintf "$(b,--%s)" long) else None) + !all_checkers |> String.concat ~sep:", " ) ) - (List.map ~f:fst !default_checkers) - [] + ~f:(fun b -> + List.iter + ~f:(fun (var, _, _, default) -> + var := if b then default || !var else not default && !var) + !all_checkers ; + b) + [] (* do all the work in ~f *) + [] + (* do all the work in ~f *) in ( annotation_reachability , biabduction @@ -1798,7 +1811,7 @@ and () = CLOpt.mk_set ~parse_mode:CLOpt.Javac version ~deprecated:["version"] ~l (** Parse Command Line Args *) -let config_file = +let inferconfig_file = let rec find dir = match Sys.file_exists ~follow_symlinks:false (dir ^/ CommandDoc.inferconfig_file) with | `Yes @@ -1845,7 +1858,7 @@ let post_parsing_initialization command_opt = (match !analyzer with Some a -> a | None -> BiAbduction) in let infer_version = - match config_file with + match inferconfig_file with | Some inferconfig -> Printf.sprintf "version %s/inferconfig %s" Version.commit (Digest.to_hex (Digest.file inferconfig)) @@ -1933,28 +1946,29 @@ let post_parsing_initialization command_opt = (* set analyzer mode to linters in linters developer mode *) if !linters_developer_mode then analyzer := Some Linters ; if !default_linters then linters_def_file := linters_def_default_file :: !linters_def_file ; - ( match !analyzer with - | Some BiAbduction - -> biabduction := true - | Some Crashcontext - -> crashcontext := true - | Some (CaptureOnly | CompileOnly | Checkers | Linters) - -> () - | None - -> let open CLOpt in - match command_opt with + ( if Option.is_none !analyzer then + match (command_opt : CLOpt.command option) with | Some Compile -> analyzer := Some CompileOnly | Some Capture -> analyzer := Some CaptureOnly | _ - -> biabduction := true - (* the default option is to run the biabduction analysis *) ) ; + -> () ) ; + ( match !analyzer with + | Some BiAbduction | None + -> disable_all_checkers () ; + (* technically the biabduction checker doesn't run in this mode, but this gives an easy way to test if the biabduction *analysis* is active *) + biabduction := true + | Some Crashcontext + -> disable_all_checkers () ; + crashcontext := true + | Some (CaptureOnly | Checkers | CompileOnly | Linters) + -> () ) ; Option.value ~default:CLOpt.Run command_opt let command, parse_args_and_return_usage_exit = let command_opt, usage_exit = - CLOpt.parse ?config_file ~usage:exe_usage startup_action initial_command + CLOpt.parse ?config_file:inferconfig_file ~usage:exe_usage startup_action initial_command in let command = post_parsing_initialization command_opt in (command, usage_exit) @@ -2462,10 +2476,7 @@ let dynamic_dispatch = | BiAbduction -> Lazy | Checkers when biabduction - -> if quandary then - F.eprintf - "WARNING: Running Quandary on Java is not compatible with the Biabduction analysis@." ; - Lazy + -> Lazy | Checkers when quandary -> Sound | _ diff --git a/infer/src/base/Config.mli b/infer/src/base/Config.mli index 79a9c951f..7731a460a 100644 --- a/infer/src/base/Config.mli +++ b/infer/src/base/Config.mli @@ -453,6 +453,8 @@ val infer_is_clang : bool val infer_is_javac : bool +val inferconfig_file : string option + val iphoneos_target_sdk_version : string option type iphoneos_target_sdk_version_path_regex = {path: Str.regexp; version: string} diff --git a/infer/src/checkers/registerCheckers.ml b/infer/src/checkers/registerCheckers.ml index 09da6614c..02dc5a654 100644 --- a/infer/src/checkers/registerCheckers.ml +++ b/infer/src/checkers/registerCheckers.ml @@ -17,57 +17,90 @@ module F = Format (* make sure SimpleChecker.ml is not dead code *) let () = if false then let module SC = SimpleChecker.Make in () -type callback = +type callback_fun = | Procedure of Callbacks.proc_callback_t | DynamicDispatch of Callbacks.proc_callback_t | Cluster of Callbacks.cluster_callback_t -let checkers = - [ ( "annotation reachability" - , Config.annotation_reachability - , [(Procedure AnnotationReachability.checker, Config.Java)] ) - ; ( "biabduction" - , Config.biabduction - , [ (Procedure Interproc.analyze_procedure, Config.Clang) - ; (DynamicDispatch Interproc.analyze_procedure, Config.Java) ] ) - ; ( "buffer overrun" - , Config.bufferoverrun - , [ (Procedure BufferOverrunChecker.checker, Config.Clang) - ; (Procedure BufferOverrunChecker.checker, Config.Java) ] ) - ; ("crashcontext", Config.crashcontext, [(Procedure BoundedCallTree.checker, Config.Java)]) - ; ("eradicate", Config.eradicate, [(Procedure Eradicate.callback_eradicate, Config.Java)]) - ; ( "fragment retains view" - , Config.fragment_retains_view - , [(Procedure FragmentRetainsViewChecker.callback_fragment_retains_view, Config.Java)] ) - ; ( "immutable cast" - , Config.immutable_cast - , [(Procedure ImmutableChecker.callback_check_immutable_cast, Config.Java)] ) - ; ("liveness", Config.liveness, [(Procedure Liveness.checker, Config.Clang)]) - ; ("printf args", Config.printf_args, [(Procedure PrintfArgs.callback_printf_args, Config.Java)]) - ; ( "nullable suggestion" - , Config.suggest_nullable - , [ (Procedure NullabilitySuggest.checker, Config.Java) - ; (Procedure NullabilitySuggest.checker, Config.Clang) ] ) - ; ("nullable checks", Config.check_nullable, [(Procedure NullabilityCheck.checker, Config.Clang)]) - ; ( "quandary" - , Config.quandary - , [ (Procedure JavaTaintAnalysis.checker, Config.Java) - ; (Procedure ClangTaintAnalysis.checker, Config.Clang) ] ) - ; ( "repeated calls" - , Config.repeated_calls - , [(Procedure RepeatedCallsChecker.callback_check_repeated_calls, Config.Java)] ) - ; ("resource leak", Config.resource_leak, [(Procedure ResourceLeaks.checker, Config.Java)]) - ; ("SIOF", Config.siof, [(Procedure Siof.checker, Config.Clang)]) - ; ("uninitialized variables", Config.uninit, [(Procedure Uninit.checker, Config.Clang)]) - ; ( "thread safety" - , Config.threadsafety - , [ (Procedure ThreadSafety.analyze_procedure, Config.Clang) - ; (Procedure ThreadSafety.analyze_procedure, Config.Java) - ; (Cluster ThreadSafety.file_analysis, Config.Clang) - ; (Cluster ThreadSafety.file_analysis, Config.Java) ] ) ] +type callback = callback_fun * Config.language -let register () = - let register_one (_, active, callbacks) = +type checker = {name: string; active: bool; callbacks: callback list} + +let all_checkers = + [ { name= "annotation reachability" + ; active= Config.annotation_reachability + ; callbacks= [(Procedure AnnotationReachability.checker, Config.Java)] } + ; { name= "biabduction" + ; active= Config.biabduction + ; callbacks= + [ (Procedure Interproc.analyze_procedure, Config.Clang) + ; (DynamicDispatch Interproc.analyze_procedure, Config.Java) ] } + ; { name= "buffer overrun" + ; active= Config.bufferoverrun + ; callbacks= + [ (Procedure BufferOverrunChecker.checker, Config.Clang) + ; (Procedure BufferOverrunChecker.checker, Config.Java) ] } + ; { name= "crashcontext" + ; active= Config.crashcontext + ; callbacks= [(Procedure BoundedCallTree.checker, Config.Java)] } + ; { name= "eradicate" + ; active= Config.eradicate + ; callbacks= [(Procedure Eradicate.callback_eradicate, Config.Java)] } + ; { name= "fragment retains view" + ; active= Config.fragment_retains_view + ; callbacks= + [(Procedure FragmentRetainsViewChecker.callback_fragment_retains_view, Config.Java)] } + ; { name= "immutable cast" + ; active= Config.immutable_cast + ; callbacks= [(Procedure ImmutableChecker.callback_check_immutable_cast, Config.Java)] } + ; { name= "liveness" + ; active= Config.liveness + ; callbacks= [(Procedure Liveness.checker, Config.Clang)] } + ; { name= "printf args" + ; active= Config.printf_args + ; callbacks= [(Procedure PrintfArgs.callback_printf_args, Config.Java)] } + ; { name= "nullable checks" + ; active= Config.check_nullable + ; callbacks= [(Procedure NullabilityCheck.checker, Config.Clang)] } + ; { name= "nullable suggestion" + ; active= Config.suggest_nullable + ; callbacks= + [ (Procedure NullabilitySuggest.checker, Config.Java) + ; (Procedure NullabilitySuggest.checker, Config.Clang) ] } + ; { name= "quandary" + ; active= Config.quandary + ; callbacks= + [ (Procedure JavaTaintAnalysis.checker, Config.Java) + ; (Procedure ClangTaintAnalysis.checker, Config.Clang) ] } + ; { name= "repeated calls" + ; active= Config.repeated_calls + ; callbacks= [(Procedure RepeatedCallsChecker.callback_check_repeated_calls, Config.Java)] } + ; { name= + "resource leak" + (** toy resource analysis to use in the infer lab, see the lab/ directory *) + ; active= Config.resource_leak + ; callbacks= + [ ( (* the checked-in version is intraprocedural, but the lab asks to make it interprocedural later on *) + Procedure ResourceLeaks.checker + , Config.Java ) ] } + ; {name= "SIOF"; active= Config.siof; callbacks= [(Procedure Siof.checker, Config.Clang)]} + ; { name= "thread safety" + ; active= Config.threadsafety + ; callbacks= + [ (Procedure ThreadSafety.analyze_procedure, Config.Clang) + ; (Procedure ThreadSafety.analyze_procedure, Config.Java) + ; (Cluster ThreadSafety.file_analysis, Config.Clang) + ; (Cluster ThreadSafety.file_analysis, Config.Java) ] } + ; { name= "uninitialized variables" + ; active= Config.uninit + ; callbacks= [(Procedure Uninit.checker, Config.Clang)] } ] + +let get_active_checkers () = + let filter_checker {active} = active in + List.filter ~f:filter_checker all_checkers + +let register checkers = + let register_one {callbacks} = let register_callback (callback, language) = match callback with | Procedure procedure_cb @@ -77,14 +110,22 @@ let register () = | Cluster cluster_cb -> Callbacks.register_cluster_callback language cluster_cb in - if active then List.iter ~f:register_callback callbacks + List.iter ~f:register_callback callbacks in List.iter ~f:register_one checkers -let pp_active_checkers fmt () = - let has_active = ref false in - List.iter checkers ~f:(fun (name, active, _) -> - if active then ( - Format.fprintf fmt "%s%s" (if !has_active then ", " else "") name ; - has_active := true ) ) ; - if not !has_active then Format.fprintf fmt "none" +module LanguageSet = Caml.Set.Make (struct + type t = Config.language + + let compare = Config.compare_language +end) + +let pp_checker fmt {name; callbacks} = + let langs_of_callbacks = + List.fold_left callbacks ~init:LanguageSet.empty ~f:(fun langs (_, lang) -> + LanguageSet.add lang langs ) + |> LanguageSet.elements + in + F.fprintf fmt "%s (%a)" name + (Pp.seq ~sep:", " (Pp.to_string ~f:Config.string_of_language)) + langs_of_callbacks diff --git a/infer/src/checkers/registerCheckers.mli b/infer/src/checkers/registerCheckers.mli index f313b145b..dea36c956 100644 --- a/infer/src/checkers/registerCheckers.mli +++ b/infer/src/checkers/registerCheckers.mli @@ -9,6 +9,10 @@ open! IStd -val register : unit -> unit +type checker -val pp_active_checkers : Format.formatter -> unit -> unit +val get_active_checkers : unit -> checker list + +val register : checker list -> unit + +val pp_checker : Format.formatter -> checker -> unit diff --git a/infer/tests/build_systems/gradle/Makefile b/infer/tests/build_systems/gradle/Makefile index 006ea4405..0bd9a0918 100644 --- a/infer/tests/build_systems/gradle/Makefile +++ b/infer/tests/build_systems/gradle/Makefile @@ -18,7 +18,7 @@ INFERPRINT_OPTIONS = --issues-tests include $(TESTS_DIR)/java.make include $(TESTS_DIR)/infer.make -infer-out/report.json: $(JAVA_DEPS) $(SOURCES) +infer-out/report.json: $(JAVA_DEPS) $(SOURCES) $(MAKEFILE_LIST) # mock version of gradle $(QUIET)PATH=$(CURDIR)/../mock:"$$PATH"; \ cd $(SOURCES_DIR) && \ diff --git a/infer/tests/build_systems/resource_leak_exception_lines/Makefile b/infer/tests/build_systems/resource_leak_exception_lines/Makefile index b2e771347..022a3e6f3 100644 --- a/infer/tests/build_systems/resource_leak_exception_lines/Makefile +++ b/infer/tests/build_systems/resource_leak_exception_lines/Makefile @@ -17,8 +17,8 @@ default: analyze .PHONY: analyze analyze: $(REPORT) -$(REPORT): - $(QUIET)$(call silent_on_success, Running analysis,\ +$(REPORT): $(JAVA_DEPS) $(MAKEFILE_LIST) SimpleLeak.java + $(QUIET)$(call silent_on_success,Running analysis,\ $(INFER_BIN) -o $(INFER_OUT) --project-root $(CURDIR) -- javac SimpleLeak.java) $(EXPECTED_TEST_OUTPUT): $(REPORT) diff --git a/infer/tests/codetoanalyze/cpp/threadsafety/Makefile b/infer/tests/codetoanalyze/cpp/threadsafety/Makefile index b12e5c66b..a7451788e 100644 --- a/infer/tests/codetoanalyze/cpp/threadsafety/Makefile +++ b/infer/tests/codetoanalyze/cpp/threadsafety/Makefile @@ -10,7 +10,7 @@ TESTS_DIR = ../../.. ANALYZER = checkers # see explanations in cpp/errors/Makefile for the custom isystem CLANG_OPTIONS = -x c++ -std=c++11 -nostdinc++ -isystem$(ROOT_DIR) -isystem$(CLANG_INCLUDES)/c++/v1/ -c -INFER_OPTIONS = --threadsafety --ml-buckets cpp --no-filtering --debug-exceptions --project-root $(TESTS_DIR) +INFER_OPTIONS = --threadsafety-only --debug-exceptions --project-root $(TESTS_DIR) INFERPRINT_OPTIONS = --issues-tests SOURCES = $(wildcard *.cpp) diff --git a/infer/tests/codetoanalyze/cpp/uninit/Makefile b/infer/tests/codetoanalyze/cpp/uninit/Makefile index f4213d5b2..61ac55eac 100644 --- a/infer/tests/codetoanalyze/cpp/uninit/Makefile +++ b/infer/tests/codetoanalyze/cpp/uninit/Makefile @@ -10,7 +10,7 @@ TESTS_DIR = ../../.. ANALYZER = checkers # see explanations in cpp/errors/Makefile for the custom isystem CLANG_OPTIONS = -x c++ -std=c++11 -nostdinc++ -isystem$(MODELS_DIR)/cpp/include -isystem$(CLANG_INCLUDES)/c++/v1/ -c -INFER_OPTIONS = --uninit --ml-buckets cpp --no-filtering --debug-exceptions --project-root $(TESTS_DIR) +INFER_OPTIONS = --uninit-only --debug-exceptions --project-root $(TESTS_DIR) INFERPRINT_OPTIONS = --issues-tests SOURCES = uninit.cpp diff --git a/infer/tests/codetoanalyze/java/crashcontext/issues.exp b/infer/tests/codetoanalyze/java/crashcontext/issues.exp index 4bd1a1940..b79386662 100644 --- a/infer/tests/codetoanalyze/java/crashcontext/issues.exp +++ b/infer/tests/codetoanalyze/java/crashcontext/issues.exp @@ -1,5 +1,5 @@ -{"stack":[{"method_name":"codetoanalyze.java.crashcontext.BranchingCallsExample.bar():void","location":{"location_type":"call_site","file":"BranchingCallsExample.java","line":24,"blame_range":[{"start_line":22,"end_line":25}]},"callees":[{"method_name":"java.lang.String.toString():java.lang.String","callees":[]}]},{"method_name":"codetoanalyze.java.crashcontext.BranchingCallsExample.foo():void","location":{"location_type":"call_site","file":"BranchingCallsExample.java","line":29,"blame_range":[{"start_line":27,"end_line":30}]},"callees":[{"method_name":"codetoanalyze.java.crashcontext.BranchingCallsExample.bar():void","location":{"location_type":"proc_start","file":"BranchingCallsExample.java","line":22,"blame_range":[{"start_line":22,"end_line":25}]},"callees":[]},{"method_name":"codetoanalyze.java.crashcontext.BranchingCallsExample.pre_bar():void","location":{"location_type":"proc_start","file":"BranchingCallsExample.java","line":14,"blame_range":[{"start_line":14,"end_line":15}]},"callees":[]}]},{"method_name":"codetoanalyze.java.crashcontext.BranchingCallsExample.main(java.lang.String[]):void","location":{"location_type":"call_site","file":"BranchingCallsExample.java","line":34,"blame_range":[{"start_line":33,"end_line":34}]},"callees":[{"method_name":"codetoanalyze.java.crashcontext.BranchingCallsExample.foo():void","location":{"location_type":"proc_start","file":"BranchingCallsExample.java","line":27,"blame_range":[{"start_line":27,"end_line":30}]},"callees":[]}]}]} -{"stack":[{"method_name":"codetoanalyze.java.crashcontext.MethodNameClashExample$A.foo():void","location":{"location_type":"call_site","file":"MethodNameClashExample.java","line":18,"blame_range":[{"start_line":16,"end_line":19}]},"callees":[{"method_name":"java.lang.String.toString():java.lang.String","callees":[]}]},{"method_name":"codetoanalyze.java.crashcontext.MethodNameClashExample$B.foo():void","location":{"location_type":"call_site","file":"MethodNameClashExample.java","line":26,"blame_range":[{"start_line":26,"end_line":26}]},"callees":[{"method_name":"codetoanalyze.java.crashcontext.MethodNameClashExample$A.foo():void","location":{"location_type":"proc_start","file":"MethodNameClashExample.java","line":16,"blame_range":[{"start_line":16,"end_line":19}]},"callees":[]}]},{"method_name":"codetoanalyze.java.crashcontext.MethodNameClashExample.main(java.lang.String[]):void","location":{"location_type":"call_site","file":"MethodNameClashExample.java","line":32,"blame_range":[{"start_line":31,"end_line":32}]},"callees":[{"method_name":"codetoanalyze.java.crashcontext.MethodNameClashExample$B.foo():void","location":{"location_type":"proc_start","file":"MethodNameClashExample.java","line":26,"blame_range":[{"start_line":26,"end_line":26}]},"callees":[]}]}]} -{"stack":[{"method_name":"codetoanalyze.java.crashcontext.MinimalCrashExample.main(java.lang.String[]):void","location":{"location_type":"call_site","file":"MinimalCrashExample.java","line":16,"blame_range":[{"start_line":14,"end_line":17}]},"callees":[{"method_name":"java.lang.String.toString():java.lang.String","callees":[]}]}]} -{"stack":[{"method_name":"codetoanalyze.java.crashcontext.MultiStackFrameCrashExample.bar():void","location":{"location_type":"call_site","file":"MultiStackFrameCrashExample.java","line":16,"blame_range":[{"start_line":14,"end_line":17}]},"callees":[{"method_name":"java.lang.String.toString():java.lang.String","callees":[]}]},{"method_name":"codetoanalyze.java.crashcontext.MultiStackFrameCrashExample.foo():void","location":{"location_type":"call_site","file":"MultiStackFrameCrashExample.java","line":20,"blame_range":[{"start_line":19,"end_line":20}]},"callees":[{"method_name":"codetoanalyze.java.crashcontext.MultiStackFrameCrashExample.bar():void","location":{"location_type":"proc_start","file":"MultiStackFrameCrashExample.java","line":14,"blame_range":[{"start_line":14,"end_line":17}]},"callees":[]}]},{"method_name":"codetoanalyze.java.crashcontext.MultiStackFrameCrashExample.main(java.lang.String[]):void","location":{"location_type":"call_site","file":"MultiStackFrameCrashExample.java","line":24,"blame_range":[{"start_line":23,"end_line":24}]},"callees":[{"method_name":"codetoanalyze.java.crashcontext.MultiStackFrameCrashExample.foo():void","location":{"location_type":"proc_start","file":"MultiStackFrameCrashExample.java","line":19,"blame_range":[{"start_line":19,"end_line":20}]},"callees":[]}]}]} -{"stack":[{"method_name":"codetoanalyze.java.crashcontext.NativeMethodExample.foo():void","location":{"location_type":"call_site","file":"NativeMethodExample.java","line":18,"blame_range":[{"start_line":16,"end_line":19}]},"callees":[{"method_name":"java.lang.String.toString():java.lang.String","callees":[]}]},{"method_name":"sun.reflect.NativeMethodAccessorImpl.invoke0","location":{"location_type":"call_site","file":"Native Method","blame_range":[]},"callees":[]},{"method_name":"sun.reflect.NativeMethodAccessorImpl.invoke","location":{"location_type":"call_site","file":"NativeMethodAccessorImpl.java","line":62,"blame_range":[]},"callees":[]},{"method_name":"sun.reflect.DelegatingMethodAccessorImpl.invoke","location":{"location_type":"call_site","file":"DelegatingMethodAccessorImpl.java","line":43,"blame_range":[]},"callees":[]},{"method_name":"java.lang.reflect.Method.invoke","location":{"location_type":"call_site","file":"Method.java","line":497,"blame_range":[]},"callees":[]},{"method_name":"codetoanalyze.java.crashcontext.NativeMethodExample.main(java.lang.String[]):void","location":{"location_type":"call_site","file":"NativeMethodExample.java","line":27,"blame_range":[{"start_line":21,"end_line":31}]},"callees":[{"method_name":"java.lang.Class.getDeclaredMethod(java.lang.String,java.lang.Class[]):java.lang.reflect.Method","callees":[]},{"method_name":"java.lang.reflect.Method.invoke(java.lang.Object,java.lang.Object[]):java.lang.Object","callees":[]},{"method_name":"__new_array","callees":[]}]}]} +{"stack":[{"method_name":"codetoanalyze.java.crashcontext.BranchingCallsExample.bar():void","location":{"location_type":"call_site","file":"BranchingCallsExample.java","line":24,"blame_range":[{"start_line":22,"end_line":24}]},"callees":[{"method_name":"java.lang.String.toString():java.lang.String","callees":[]}]},{"method_name":"codetoanalyze.java.crashcontext.BranchingCallsExample.foo():void","location":{"location_type":"call_site","file":"BranchingCallsExample.java","line":29,"blame_range":[{"start_line":27,"end_line":30}]},"callees":[{"method_name":"codetoanalyze.java.crashcontext.BranchingCallsExample.bar():void","location":{"location_type":"proc_start","file":"BranchingCallsExample.java","line":22,"blame_range":[{"start_line":22,"end_line":24}]},"callees":[]},{"method_name":"codetoanalyze.java.crashcontext.BranchingCallsExample.pre_bar():void","location":{"location_type":"proc_start","file":"BranchingCallsExample.java","line":14,"blame_range":[{"start_line":14,"end_line":15}]},"callees":[]}]},{"method_name":"codetoanalyze.java.crashcontext.BranchingCallsExample.main(java.lang.String[]):void","location":{"location_type":"call_site","file":"BranchingCallsExample.java","line":34,"blame_range":[{"start_line":33,"end_line":34}]},"callees":[{"method_name":"codetoanalyze.java.crashcontext.BranchingCallsExample.foo():void","location":{"location_type":"proc_start","file":"BranchingCallsExample.java","line":27,"blame_range":[{"start_line":27,"end_line":30}]},"callees":[]}]}]} +{"stack":[{"method_name":"codetoanalyze.java.crashcontext.MethodNameClashExample$A.foo():void","location":{"location_type":"call_site","file":"MethodNameClashExample.java","line":18,"blame_range":[{"start_line":16,"end_line":18}]},"callees":[{"method_name":"java.lang.String.toString():java.lang.String","callees":[]}]},{"method_name":"codetoanalyze.java.crashcontext.MethodNameClashExample$B.foo():void","location":{"location_type":"call_site","file":"MethodNameClashExample.java","line":26,"blame_range":[{"start_line":26,"end_line":26}]},"callees":[{"method_name":"codetoanalyze.java.crashcontext.MethodNameClashExample$A.foo():void","location":{"location_type":"proc_start","file":"MethodNameClashExample.java","line":16,"blame_range":[{"start_line":16,"end_line":18}]},"callees":[]}]},{"method_name":"codetoanalyze.java.crashcontext.MethodNameClashExample.main(java.lang.String[]):void","location":{"location_type":"call_site","file":"MethodNameClashExample.java","line":32,"blame_range":[{"start_line":31,"end_line":32}]},"callees":[{"method_name":"codetoanalyze.java.crashcontext.MethodNameClashExample$B.foo():void","location":{"location_type":"proc_start","file":"MethodNameClashExample.java","line":26,"blame_range":[{"start_line":26,"end_line":26}]},"callees":[]}]}]} +{"stack":[{"method_name":"codetoanalyze.java.crashcontext.MinimalCrashExample.main(java.lang.String[]):void","location":{"location_type":"call_site","file":"MinimalCrashExample.java","line":16,"blame_range":[{"start_line":14,"end_line":16}]},"callees":[{"method_name":"java.lang.String.toString():java.lang.String","callees":[]}]}]} +{"stack":[{"method_name":"codetoanalyze.java.crashcontext.MultiStackFrameCrashExample.bar():void","location":{"location_type":"call_site","file":"MultiStackFrameCrashExample.java","line":16,"blame_range":[{"start_line":14,"end_line":16}]},"callees":[{"method_name":"java.lang.String.toString():java.lang.String","callees":[]}]},{"method_name":"codetoanalyze.java.crashcontext.MultiStackFrameCrashExample.foo():void","location":{"location_type":"call_site","file":"MultiStackFrameCrashExample.java","line":20,"blame_range":[{"start_line":19,"end_line":20}]},"callees":[{"method_name":"codetoanalyze.java.crashcontext.MultiStackFrameCrashExample.bar():void","location":{"location_type":"proc_start","file":"MultiStackFrameCrashExample.java","line":14,"blame_range":[{"start_line":14,"end_line":16}]},"callees":[]}]},{"method_name":"codetoanalyze.java.crashcontext.MultiStackFrameCrashExample.main(java.lang.String[]):void","location":{"location_type":"call_site","file":"MultiStackFrameCrashExample.java","line":24,"blame_range":[{"start_line":23,"end_line":24}]},"callees":[{"method_name":"codetoanalyze.java.crashcontext.MultiStackFrameCrashExample.foo():void","location":{"location_type":"proc_start","file":"MultiStackFrameCrashExample.java","line":19,"blame_range":[{"start_line":19,"end_line":20}]},"callees":[]}]}]} +{"stack":[{"method_name":"codetoanalyze.java.crashcontext.NativeMethodExample.foo():void","location":{"location_type":"call_site","file":"NativeMethodExample.java","line":18,"blame_range":[{"start_line":16,"end_line":18}]},"callees":[{"method_name":"java.lang.String.toString():java.lang.String","callees":[]}]},{"method_name":"sun.reflect.NativeMethodAccessorImpl.invoke0","location":{"location_type":"call_site","file":"Native Method","blame_range":[]},"callees":[]},{"method_name":"sun.reflect.NativeMethodAccessorImpl.invoke","location":{"location_type":"call_site","file":"NativeMethodAccessorImpl.java","line":62,"blame_range":[]},"callees":[]},{"method_name":"sun.reflect.DelegatingMethodAccessorImpl.invoke","location":{"location_type":"call_site","file":"DelegatingMethodAccessorImpl.java","line":43,"blame_range":[]},"callees":[]},{"method_name":"java.lang.reflect.Method.invoke","location":{"location_type":"call_site","file":"Method.java","line":497,"blame_range":[]},"callees":[]},{"method_name":"codetoanalyze.java.crashcontext.NativeMethodExample.main(java.lang.String[]):void","location":{"location_type":"call_site","file":"NativeMethodExample.java","line":27,"blame_range":[{"start_line":21,"end_line":29}]},"callees":[{"method_name":"java.lang.Class.getDeclaredMethod(java.lang.String,java.lang.Class[]):java.lang.reflect.Method","callees":[]},{"method_name":"java.lang.reflect.Method.invoke(java.lang.Object,java.lang.Object[]):java.lang.Object","callees":[]},{"method_name":"__new_array","callees":[]}]}]}