diff --git a/infer/src/backend/InferAnalyze.re b/infer/src/backend/InferAnalyze.re index a6e26b8d8..761e9ead8 100644 --- a/infer/src/backend/InferAnalyze.re +++ b/infer/src/backend/InferAnalyze.re @@ -168,6 +168,9 @@ let main makefile => { List.exists f::(fun cl => DB.string_crc_has_extension ext::"java" (DB.source_dir_to_string cl)) all_clusters; + if Config.print_active_checkers { + L.stderr "Active checkers: %a@." RegisterCheckers.pp_active_checkers () + }; print_stdout_legend (); if (Config.per_procedure_parallelism && not (is_java ())) { /* Java uses ZipLib which is incompatible with forking */ diff --git a/infer/src/backend/callbacks.ml b/infer/src/backend/callbacks.ml index d26f06c34..c5a0331a8 100644 --- a/infer/src/backend/callbacks.ml +++ b/infer/src/backend/callbacks.ml @@ -41,10 +41,6 @@ let register_procedure_callback language_opt (callback: proc_callback_t) = let register_cluster_callback language_opt (callback: cluster_callback_t) = cluster_callbacks := (language_opt, callback):: !cluster_callbacks -let unregister_all_callbacks () = - procedure_callbacks := []; - cluster_callbacks := [] - (** Collect what we need to know about a procedure for the analysis. *) let get_procedure_definition exe_env proc_name = let tenv = Exe_env.get_tenv exe_env proc_name in diff --git a/infer/src/backend/callbacks.mli b/infer/src/backend/callbacks.mli index 1a4642770..65af29c17 100644 --- a/infer/src/backend/callbacks.mli +++ b/infer/src/backend/callbacks.mli @@ -41,8 +41,5 @@ val register_procedure_callback : Config.language option -> proc_callback_t -> u (** register a cluster callback *) val register_cluster_callback : Config.language option -> cluster_callback_t -> unit -(** un-register all the procedure callbacks currently registered *) -val unregister_all_callbacks : unit -> unit - (** Invoke all the registered callbacks. *) val iterate_callbacks : Cg.t -> Exe_env.t -> unit diff --git a/infer/src/base/Config.ml b/infer/src/base/Config.ml index b492619f4..6f148c763 100644 --- a/infer/src/base/Config.ml +++ b/infer/src/base/Config.ml @@ -508,12 +508,101 @@ and angelic_execution = CLOpt.mk_bool ~deprecated:["angelic_execution"] ~long:"angelic-execution" ~default:true "Angelic execution, where the analysis ignores errors caused by unknown procedure calls" -and annotation_reachability = - CLOpt.mk_bool ~long:"annotation-reachability" ~in_help:CLOpt.[Analyze, manual_generic] - "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 (annotation_reachability, + biabduction, + bufferoverrun, + crashcontext, + default_checkers, + eradicate, + fragment_retains_view, + immutable_cast, + printf_args, + quandary, + repeated_calls, + siof, + threadsafety) = + let annotation_reachability = + CLOpt.mk_bool ~long:"annotation-reachability" ~in_help:CLOpt.[Analyze, manual_generic] + ~default:true + "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 = + CLOpt.mk_bool ~long:"biabduction" ~in_help:CLOpt.[Analyze, manual_generic] + "the separation logic based bi-abduction analysis using the checkers framework" + + and bufferoverrun = + CLOpt.mk_bool ~long:"bufferoverrun" ~in_help:CLOpt.[Analyze, manual_generic] + "the buffer overrun analysis" + + and crashcontext = + CLOpt.mk_bool ~long:"crashcontext" ~in_help:CLOpt.[Analyze, manual_generic] + "the crashcontext checker for Java stack trace context reconstruction" + + and eradicate = + CLOpt.mk_bool ~long:"eradicate" ~in_help:CLOpt.[Analyze, manual_generic] + "the eradicate @Nullable checker for Java annotations" + + and fragment_retains_view = + CLOpt.mk_bool ~long:"fragment-retains-view" ~in_help:CLOpt.[Analyze, manual_generic] + ~default:true + "detects when Android fragments are not explicitly nullified before becoming unreabable" + + and immutable_cast = + CLOpt.mk_bool ~long:"immutable-cast" ~in_help:CLOpt.[Analyze, manual_generic] + ~default:true + "the detection of object cast from immutable type to mutable type. \ + For instance, it will detect cast from ImmutableList to List, ImmutableMap to Map, \ + and ImmutableSet to Set." + + and printf_args = + CLOpt.mk_bool ~long:"printf-args" ~in_help:CLOpt.[Analyze, manual_generic] + ~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 = + CLOpt.mk_bool ~long:"repeated-calls" ~in_help:CLOpt.[Analyze, manual_generic] + "check for repeated calls" + + and quandary = + CLOpt.mk_bool ~long:"quandary" ~in_help:CLOpt.[Analyze, manual_generic] ~default:true + "the quandary taint analysis" + + and siof = + CLOpt.mk_bool ~long:"siof" ~in_help:CLOpt.[Analyze, manual_generic] ~default:true + "the Static Initialization Order Fiasco analysis (C++ only)" + + and threadsafety = + CLOpt.mk_bool ~long:"threadsafety" ~in_help:CLOpt.[Analyze, manual_generic] ~default:true + "the thread safety analysis" in + + (* IMPORTANT: keep in sync with the checkers that have ~default:true above *) + let default_checkers = + CLOpt.mk_bool_group ~long:"default-checkers" ~in_help:CLOpt.[Analyze, manual_generic] + ~default:true + "Default checkers: $(b,--annotation-reachability), $(b,--fragments-retains-view), \ + $(b,--immutable-cast), $(b,--printf-args), $(b,--quandary), $(b,--siof), $(b,--threadsafety)" + [annotation_reachability; fragment_retains_view; immutable_cast; printf_args; quandary; + siof; threadsafety] + [] in + + (annotation_reachability, + biabduction, + bufferoverrun, + crashcontext, + default_checkers, + eradicate, + fragment_retains_view, + immutable_cast, + printf_args, + quandary, + repeated_calls, + siof, + threadsafety) and annotation_reachability_custom_pairs = CLOpt.mk_json ~long:"annotation-reachability-custom-pairs" @@ -533,10 +622,6 @@ and ast_file = CLOpt.mk_path_opt ~deprecated:["ast"] ~long:"ast-file" ~meta:"file" "AST file for the translation" -and biabduction = - CLOpt.mk_bool ~long:"biabduction" ~in_help:CLOpt.[Analyze, manual_generic] - "the separation logic based bi-abduction analysis using the checkers framework" - and blacklist = CLOpt.mk_string_opt ~deprecated:["-blacklist-regex";"-blacklist"] ~long:"buck-blacklist" ~in_help:CLOpt.[Run, manual_buck_flavors; Capture, manual_buck_flavors] @@ -571,10 +656,6 @@ and buck_out = CLOpt.mk_path_opt ~long:"buck-out" ~in_help:CLOpt.[Capture, manual_buck_java] ~meta:"dir" "Specify the root directory of buck-out" -and bufferoverrun = - CLOpt.mk_bool ~long:"bufferoverrun" ~in_help:CLOpt.[Analyze, manual_generic] - "the buffer overrun analysis" - and bugs_csv = CLOpt.mk_path_opt ~deprecated:["bugs"] ~long:"issues-csv" ~in_help:CLOpt.[Report, manual_generic] @@ -609,10 +690,6 @@ and changed_files_index = "Specify the file containing the list of source files from which reactive analysis should \ start. Source files should be specified relative to project root or be absolute" -and checkers_repeated_calls = - CLOpt.mk_bool ~long:"checkers-repeated-calls" ~in_help:CLOpt.[Analyze, manual_generic] - "check for repeated calls" - and clang_biniou_file = CLOpt.mk_path_opt ~long:"clang-biniou-file" ~in_help:CLOpt.[Capture, manual_clang] ~meta:"file" @@ -681,10 +758,6 @@ and copy_propagation = CLOpt.mk_bool ~deprecated:["copy-propagation"] ~long:"copy-propagation" "Perform copy-propagation on the IR" -and crashcontext = - CLOpt.mk_bool ~long:"crashcontext" ~in_help:CLOpt.[Analyze, manual_generic] - "the crashcontext checker for Java stack trace context reconstruction" - and cxx = CLOpt.mk_bool ~deprecated:["cxx-experimental"] ~long:"cxx" ~default:true @@ -847,10 +920,6 @@ and enable_checks = CLOpt.mk_string_list ~deprecated:["enable_checks"] ~long:"enable-checks" ~meta:"error name" "Show reports coming from this type of errors" -and eradicate = - CLOpt.mk_bool ~long:"eradicate" ~in_help:CLOpt.[Analyze, manual_generic] - "the eradicate @Nullable checker for Java annotations" - and eradicate_condition_redundant = CLOpt.mk_bool ~long:"eradicate-condition-redundant" "Condition redundant warnings" @@ -923,10 +992,6 @@ and flavors = "Buck integration using Buck flavors (clang only), eg $(i,`infer --flavors -- buck build \ //foo:bar#infer`)" -and fragment_retains_view = - CLOpt.mk_bool ~long:"fragment-retains-view" ~in_help:CLOpt.[Analyze, manual_generic] - "detects when Android fragments are not explicitly nullified before becoming unreabable" - and from_json_report = CLOpt.mk_path_opt ~long:"from-json-report" ~in_help:CLOpt.[Report, manual_generic] @@ -977,12 +1042,6 @@ and icfg_dotty_outfile = "If set, specifies path where .dot file should be written, it overrides the path for all \ other options that would generate icfg file otherwise" -and immutable_cast = - CLOpt.mk_bool ~long:"immutable-cast" ~in_help:CLOpt.[Analyze, manual_generic] - "the detection of object cast from immutable type to mutable type. \ - For instance, it will detect cast from ImmutableList to List, ImmutableMap to Map, \ - and ImmutableSet to Set." - and infer_cache = CLOpt.mk_path_opt ~deprecated:["infer_cache"; "-infer_cache"] ~long:"infer-cache" ~meta:"dir" "Select a directory to contain the infer cache (Buck and Java only)" @@ -1146,16 +1205,14 @@ and precondition_stats = CLOpt.mk_bool ~deprecated:["precondition_stats"] ~long:"precondition-stats" "Print stats about preconditions to standard output" +and print_active_checkers = + CLOpt.mk_bool ~long:"print-active-checkers" ~in_help:CLOpt.[Analyze, manual_generic] + "Print the active checkers before starting the analysis" + and print_builtins = CLOpt.mk_bool ~deprecated:["print_builtins"] ~long:"print-builtins" "Print the builtin functions and exit" -and printf_args = - CLOpt.mk_bool ~long:"printf-args" ~in_help:CLOpt.[Analyze, manual_generic] - "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 print_using_diff = CLOpt.mk_bool ~deprecated_no:["noprintdiff"] ~long:"print-using-diff" ~default:true "Highlight the difference w.r.t. the previous prop when printing symbolic execution debug info" @@ -1189,10 +1246,6 @@ and project_root = Report, manual_generic] ~meta:"dir" "Specify the root directory of the project" -and quandary = - CLOpt.mk_bool ~long:"quandary" ~in_help:CLOpt.[Analyze, manual_generic] - "the quandary taint analysis" - and quandary_endpoints = CLOpt.mk_json ~long:"quandary-endpoints" ~in_help:CLOpt.[Analyze, manual_quandary] @@ -1285,10 +1338,6 @@ and seconds_per_iteration = CLOpt.mk_float_opt ~deprecated:["seconds_per_iteration"] ~long:"seconds-per-iteration" ~meta:"float" "Set the number of seconds per iteration (see $(b,--iterations))" -and siof = - CLOpt.mk_bool ~long:"siof" ~in_help:CLOpt.[Analyze, manual_generic] - "the Static Initialization Order Fiasco analysis (C++ only)" - and siof_safe_methods = CLOpt.mk_string_list ~long:"siof-safe-methods" ~in_help:CLOpt.[Analyze, manual_siof] @@ -1399,10 +1448,6 @@ and threadsafe_aliases = ~in_help:CLOpt.[Analyze, manual_threadsafety] "Specify custom annotations that should be considered aliases of @ThreadSafe" -and threadsafety = - CLOpt.mk_bool ~long:"threadsafety" ~in_help:CLOpt.[Analyze, manual_generic] - "the thread safety analysis" - and trace_join = CLOpt.mk_bool ~deprecated:["trace_join"] ~long:"trace-join" "Detailed tracing information during prop join operations" @@ -1693,7 +1738,6 @@ and bugs_txt = !bugs_txt and changed_files_index = !changed_files_index and calls_csv = !calls_csv and dump_duplicate_symbols = !dump_duplicate_symbols -and checkers_repeated_calls = !checkers_repeated_calls and clang_biniou_file = !clang_biniou_file and clang_ignore_regex = !clang_ignore_regex and clang_include_to_override_regex = !clang_include_to_override_regex @@ -1777,8 +1821,9 @@ and per_procedure_parallelism = !per_procedure_parallelism and pmd_xml = !pmd_xml and precondition_stats = !precondition_stats and printf_args = !printf_args -and print_logs = !print_logs +and print_active_checkers = !print_active_checkers and print_builtins = !print_builtins +and print_logs = !print_logs and print_types = !print_types and print_using_diff = !print_using_diff and procedures_per_process = !procedures_per_process @@ -1792,6 +1837,7 @@ and quandary_sinks = !quandary_sinks and quiet = !quiet and reactive_mode = !reactive and reactive_capture = !reactive_capture +and repeated_calls = !repeated_calls and report_current = !report_current and report_custom_error = !report_custom_error and report_formatter = !report_formatter diff --git a/infer/src/base/Config.mli b/infer/src/base/Config.mli index 129304eda..4cd267230 100644 --- a/infer/src/base/Config.mli +++ b/infer/src/base/Config.mli @@ -189,7 +189,6 @@ val calls_csv : string option (** directory where the results of the capture phase are stored *) val captured_dir : string -val checkers_repeated_calls : bool val clang_biniou_file : string option val clang_frontend_action_string : string val clang_frontend_do_capture : bool @@ -289,8 +288,9 @@ val only_footprint : bool val out_file_cmdline : string val pmd_xml : bool val precondition_stats : bool -val print_logs : bool +val print_active_checkers : bool val print_builtins : bool +val print_logs : bool val print_types : bool val print_using_diff : bool val printf_args : bool @@ -305,6 +305,7 @@ val quandary_sinks : Yojson.Basic.json val quiet : bool val reactive_mode : bool val reactive_capture : bool +val repeated_calls : bool val report_current : string option val report_formatter : [`No_formatter | `Phabricator_formatter] val report_hook : string option diff --git a/infer/src/checkers/registerCheckers.ml b/infer/src/checkers/registerCheckers.ml index e44d8cb89..097333794 100644 --- a/infer/src/checkers/registerCheckers.ml +++ b/infer/src/checkers/registerCheckers.ml @@ -14,53 +14,55 @@ open! IStd module L = Logging module F = Format -let enabled_by_default = - (* True when no checker is explicitely enabled from the command line *) - let open Config in - not (biabduction || bufferoverrun || checkers_repeated_calls || crashcontext - || eradicate || quandary || siof || threadsafety) +(* make sure SimpleChecker.ml is not dead code *) +let () = if false then (let module SC = SimpleChecker.Make in ()) -(** Flags to activate checkers. *) -let active_procedure_checkers () = +type callback = + | Procedure of Callbacks.proc_callback_t + | Cluster of Callbacks.cluster_callback_t - let java_checkers = - let l = - [ - FragmentRetainsViewChecker.callback_fragment_retains_view, enabled_by_default - || Config.fragment_retains_view; - Eradicate.callback_eradicate, Config.eradicate; - BoundedCallTree.checker, Config.crashcontext; - JavaTaintAnalysis.checker, Config.quandary || enabled_by_default; - ImmutableChecker.callback_check_immutable_cast, enabled_by_default - || Config.immutable_cast; - RepeatedCallsChecker.callback_check_repeated_calls, Config.checkers_repeated_calls; - PrintfArgs.callback_printf_args, enabled_by_default || Config.printf_args; - AnnotationReachability.checker, enabled_by_default || Config.annotation_reachability; - BufferOverrunChecker.checker, Config.bufferoverrun; - ThreadSafety.analyze_procedure, enabled_by_default || Config.threadsafety; - Interproc.analyze_procedure, Config.biabduction; - ] in - (* make sure SimpleChecker.ml is not dead code *) - if false then (let module SC = SimpleChecker.Make in ()); - List.map ~f:(fun (x, y) -> (x, y, Some Config.Java)) l in - let c_cpp_checkers = - let l = - [ - ClangTaintAnalysis.checker, Config.quandary; - Siof.checker, enabled_by_default || Config.siof; - ThreadSafety.analyze_procedure, Config.threadsafety; - BufferOverrunChecker.checker, Config.bufferoverrun; - Interproc.analyze_procedure, Config.biabduction; - ] in - List.map ~f:(fun (x, y) -> (x, y, Some Config.Clang)) l in - - java_checkers @ c_cpp_checkers - -let active_cluster_checkers () = - [(ThreadSafety.file_analysis, enabled_by_default || Config.threadsafety, Some Config.Java)] +let checkers = [ + "annotation reachability", Config.annotation_reachability, + [Procedure AnnotationReachability.checker, Config.Java]; + "biabduction", Config.biabduction, + [Procedure Interproc.analyze_procedure, Config.Clang; + Procedure 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]; + "printf args", Config.printf_args, [Procedure PrintfArgs.callback_printf_args, Config.Java]; + "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]; + "SIOF", Config.siof, [Procedure Siof.checker, Config.Clang]; + "thread safety", Config.threadsafety, + [Procedure ThreadSafety.analyze_procedure, Config.Clang; + Procedure ThreadSafety.analyze_procedure, Config.Java; + Cluster ThreadSafety.file_analysis, Config.Java] +] let register () = - let register registry (callback, active, language_opt) = - if active then registry language_opt callback in - List.iter ~f:(register Callbacks.register_procedure_callback) (active_procedure_checkers ()); - List.iter ~f:(register Callbacks.register_cluster_callback) (active_cluster_checkers ()) + let register_one (_, active, callbacks) = + let register_callback (callback, language) = match callback with + | Procedure procedure_cb -> + Callbacks.register_procedure_callback (Some language) procedure_cb + | Cluster cluster_cb -> + Callbacks.register_cluster_callback (Some language) cluster_cb in + if active then 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" diff --git a/infer/src/checkers/registerCheckers.mli b/infer/src/checkers/registerCheckers.mli index c928d0200..f313b145b 100644 --- a/infer/src/checkers/registerCheckers.mli +++ b/infer/src/checkers/registerCheckers.mli @@ -10,3 +10,5 @@ open! IStd val register : unit -> unit + +val pp_active_checkers : Format.formatter -> unit -> unit diff --git a/infer/src/checkers/repeatedCallsChecker.ml b/infer/src/checkers/repeatedCallsChecker.ml index 9fc73af62..5567bb971 100644 --- a/infer/src/checkers/repeatedCallsChecker.ml +++ b/infer/src/checkers/repeatedCallsChecker.ml @@ -167,7 +167,7 @@ let callback_check_repeated_calls callback_args = let checks = { TypeCheck.eradicate = false; - check_extension = Config.checkers_repeated_calls; + check_extension = Config.repeated_calls; check_ret_type = []; } in MainRepeatedCalls.callback checks callback_args diff --git a/infer/tests/clang.make b/infer/tests/clang.make index 86d1c8ff5..b38b4134a 100644 --- a/infer/tests/clang.make +++ b/infer/tests/clang.make @@ -14,9 +14,9 @@ OBJECTS = $(foreach source,$(SOURCES),$(basename $(source)).o) include $(TESTS_DIR)/infer.make include $(TESTS_DIR)/clang-base.make -infer-out$(TEST_SUFFIX)/report.json: $(CLANG_DEPS) $(SOURCES) $(HEADERS) $(TESTS_DIR)/.inferconfig +infer-out$(TEST_SUFFIX)/report.json: $(CLANG_DEPS) $(SOURCES) $(HEADERS) $(TESTS_DIR)/.inferconfig $(MAKEFILE_LIST) $(QUIET)$(call silent_on_success,Testing infer/clang$(ANALYZER_STRING) in $(TEST_REL_DIR),\ - $(INFER_BIN) --results-dir $(@D) --dump-duplicate-symbols \ + $(INFER_BIN) --results-dir $(@D) --dump-duplicate-symbols --no-default-checkers \ $(INFER_OPTIONS) -a $(ANALYZER) -- \ clang $(CLANG_OPTIONS) $(SOURCES)) $(QUIET)$(call check_no_duplicates,infer-out$(TEST_SUFFIX)/duplicates.txt) diff --git a/infer/tests/codetoanalyze/java/checkers/Makefile b/infer/tests/codetoanalyze/java/checkers/Makefile index 8be93bd90..243926dad 100644 --- a/infer/tests/codetoanalyze/java/checkers/Makefile +++ b/infer/tests/codetoanalyze/java/checkers/Makefile @@ -8,7 +8,7 @@ TESTS_DIR = ../../.. ANALYZER = checkers -INFER_OPTIONS = --no-filtering --debug-exceptions +INFER_OPTIONS = --no-filtering --debug-exceptions --default-checkers INFERPRINT_OPTIONS = --issues-tests SOURCES = $(wildcard *.java) diff --git a/infer/tests/codetoanalyze/java/checkers/issues.exp b/infer/tests/codetoanalyze/java/checkers/issues.exp index bcb3eff29..041c94b21 100644 --- a/infer/tests/codetoanalyze/java/checkers/issues.exp +++ b/infer/tests/codetoanalyze/java/checkers/issues.exp @@ -25,7 +25,7 @@ codetoanalyze/java/checkers/ExpensiveInheritanceExample.java, void ExpensiveInhe codetoanalyze/java/checkers/ExpensiveInheritanceExample.java, void ExpensiveInheritanceExample.reportsAssumingObjectOfTypeA(), 2, CHECKERS_CALLS_EXPENSIVE_METHOD, [] codetoanalyze/java/checkers/ExpensiveInheritanceExample.java, void ExpensiveInheritanceExample.reportsBecauseFooIsExpensiveInA(A), 1, CHECKERS_CALLS_EXPENSIVE_METHOD, [] codetoanalyze/java/checkers/ExpensiveInterfaceExample.java, void ExpensiveInterfaceExample$ImplementsInterface.m1(), 1, CHECKERS_CALLS_EXPENSIVE_METHOD, [] -codetoanalyze/java/checkers/ExpensiveSubtypingExample.java, void ExpensiveSubtypingExample.m3(), 0, CHECKERS_EXPENSIVE_OVERRIDES_UNANNOTATED, [] +codetoanalyze/java/checkers/ExpensiveSubtypingExample.java, void ExpensiveSubtypingExample.m3(), 0, CHECKERS_EXPENSIVE_OVERRIDES_UNANNOTATED, [return from a call to void ExpensiveSubtypingExample.m3()] codetoanalyze/java/checkers/FragmentRetainsViewExample.java, void FragmentRetainsViewExample.onDestroyView(), 0, CHECKERS_FRAGMENT_RETAINS_VIEW, [return from a call to void FragmentRetainsViewExample.onDestroyView()] codetoanalyze/java/checkers/FragmentRetainsViewExample.java, void FragmentRetainsViewExample.onDestroyView(), 0, CHECKERS_FRAGMENT_RETAINS_VIEW, [return from a call to void FragmentRetainsViewExample.onDestroyView()] codetoanalyze/java/checkers/FragmentRetainsViewExample.java, void FragmentRetainsViewExample.onDestroyView(), 0, CHECKERS_FRAGMENT_RETAINS_VIEW, [return from a call to void FragmentRetainsViewExample.onDestroyView()] diff --git a/infer/tests/codetoanalyze/java/crashcontext/issues.exp b/infer/tests/codetoanalyze/java/crashcontext/issues.exp index b79386662..4bd1a1940 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":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":[]}]}]} +{"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":[]}]}]} diff --git a/infer/tests/javac.make b/infer/tests/javac.make index 4361dd997..a55a5eeff 100644 --- a/infer/tests/javac.make +++ b/infer/tests/javac.make @@ -22,7 +22,8 @@ PROJECT_ROOT ?= $(TESTS_DIR) $(OBJECTS): $(SOURCES) $(JAVAC) -cp $(CLASSPATH) $(SOURCES) -infer-out/report.json: $(JAVA_DEPS) $(SOURCES) +infer-out/report.json: $(JAVA_DEPS) $(SOURCES) $(MAKEFILE_LIST) $(QUIET)$(call silent_on_success,Testing infer/java$(ANALYZER_STRING) in $(TEST_REL_DIR),\ - $(INFER_BIN) -a $(ANALYZER) --project-root $(PROJECT_ROOT) $(INFER_OPTIONS) -- \ + $(INFER_BIN) -a $(ANALYZER) --no-default-checkers --project-root $(PROJECT_ROOT) \ + $(INFER_OPTIONS) -- \ $(JAVAC) -cp $(CLASSPATH) $(SOURCES))