From ea7b185b6bb4d258cdb4d7f30d69586b0a0bfc3d Mon Sep 17 00:00:00 2001 From: Nikos Gorogiannis Date: Mon, 22 Oct 2018 07:59:24 -0700 Subject: [PATCH] [classloads] add option for specifying root methods and add tests Summary: Reports will now be issued for the class loads of the methods specified by the option `--class-loads-roots`. Reviewed By: jvillard Differential Revision: D10466492 fbshipit-source-id: 91456d723 --- Makefile | 2 +- infer/man/man1/infer-analyze.txt | 11 +++++---- infer/man/man1/infer-full.txt | 18 +++++++++----- infer/man/man1/infer.txt | 12 +++++----- infer/src/base/Config.ml | 8 ++++++- infer/src/base/Config.mli | 2 ++ infer/src/base/IssueType.ml | 2 ++ infer/src/base/IssueType.mli | 2 ++ infer/src/concurrency/classLoads.ml | 16 +++++++++++++ infer/src/concurrency/classLoadsDomain.ml | 20 +++++++++------- infer/src/concurrency/classLoadsDomain.mli | 7 ++++++ .../codetoanalyze/java/classloads/Basic.java | 24 +++++++++++++++++++ .../codetoanalyze/java/classloads/Makefile | 12 ++++++++++ .../codetoanalyze/java/classloads/issues.exp | 1 + 14 files changed, 110 insertions(+), 27 deletions(-) create mode 100644 infer/tests/codetoanalyze/java/classloads/Basic.java create mode 100644 infer/tests/codetoanalyze/java/classloads/Makefile create mode 100644 infer/tests/codetoanalyze/java/classloads/issues.exp diff --git a/Makefile b/Makefile index 2d8894284..9aa66c642 100644 --- a/Makefile +++ b/Makefile @@ -106,7 +106,7 @@ BUILD_SYSTEMS_TESTS += \ racerd_dedup DIRECT_TESTS += \ - java_checkers java_eradicate java_infer java_lab java_tracing java_quandary \ + java_checkers java_classloads java_eradicate java_infer java_lab java_tracing java_quandary \ java_racerd java_stability java_crashcontext java_hoisting java_hoistingExpensive java_starvation java_performance java_purity ifneq ($(ANT),no) BUILD_SYSTEMS_TESTS += ant diff --git a/infer/man/man1/infer-analyze.txt b/infer/man/man1/infer-analyze.txt index 002e881b7..026c8b083 100644 --- a/infer/man/man1/infer-analyze.txt +++ b/infer/man/man1/infer-analyze.txt @@ -55,12 +55,13 @@ OPTIONS Activates: Enable --check-nullable and disable all other checkers (Conversely: --no-check-nullable-only) - --classloads - Activates: class loading analysis (Conversely: --no-classloads) + --class-loads + Activates: Java class loading analysis (Conversely: + --no-class-loads) - --classloads-only - Activates: Enable --classloads and disable all other checkers - (Conversely: --no-classloads-only) + --class-loads-only + Activates: Enable --class-loads and disable all other checkers + (Conversely: --no-class-loads-only) --continue Activates: Continue the capture for the reactive analysis, diff --git a/infer/man/man1/infer-full.txt b/infer/man/man1/infer-full.txt index 2fb7b1960..d1f56b1cd 100644 --- a/infer/man/man1/infer-full.txt +++ b/infer/man/man1/infer-full.txt @@ -147,13 +147,13 @@ OPTIONS Specify a file containing the AST of the program, in biniou format See also infer-capture(1). - --classloads - Activates: class loading analysis (Conversely: --no-classloads) - See also infer-analyze(1). + --class-loads + Activates: Java class loading analysis (Conversely: + --no-class-loads) See also infer-analyze(1). - --classloads-only - Activates: Enable --classloads and disable all other checkers - (Conversely: --no-classloads-only) See also infer-analyze(1). + --class-loads-only + Activates: Enable --class-loads and disable all other checkers + (Conversely: --no-class-loads-only) See also infer-analyze(1). --compilation-database +path File that contain compilation commands (can be specified multiple @@ -1006,6 +1006,12 @@ INTERNAL OPTIONS --clang-include-to-override-regex-reset Cancel the effect of --clang-include-to-override-regex. + --class-loads-roots +string + Report class loads of this list of Java methods + + --class-loads-roots-reset + Set --class-loads-roots to the empty list. + --classpath string Specify the Java classpath diff --git a/infer/man/man1/infer.txt b/infer/man/man1/infer.txt index a4c3cae91..fa98c4f03 100644 --- a/infer/man/man1/infer.txt +++ b/infer/man/man1/infer.txt @@ -147,13 +147,13 @@ OPTIONS Specify a file containing the AST of the program, in biniou format See also infer-capture(1). - --classloads - Activates: class loading analysis (Conversely: --no-classloads) - See also infer-analyze(1). + --class-loads + Activates: Java class loading analysis (Conversely: + --no-class-loads) See also infer-analyze(1). - --classloads-only - Activates: Enable --classloads and disable all other checkers - (Conversely: --no-classloads-only) See also infer-analyze(1). + --class-loads-only + Activates: Enable --class-loads and disable all other checkers + (Conversely: --no-class-loads-only) See also infer-analyze(1). --compilation-database +path File that contain compilation commands (can be specified multiple diff --git a/infer/src/base/Config.ml b/infer/src/base/Config.ml index de3882648..4d117210f 100644 --- a/infer/src/base/Config.ml +++ b/infer/src/base/Config.ml @@ -631,7 +631,7 @@ and ( annotation_reachability and check_nullable = mk_checker ~long:"check-nullable" "checks that values annotated with nullable are always checked for null before dereference" - and class_loads = mk_checker ~long:"classloads" ~default:false "class loading analysis" + and class_loads = mk_checker ~long:"class-loads" ~default:false "Java class loading analysis" and cost = mk_checker ~long:"cost" ~default:false "checker for performance cost analysis" and crashcontext = mk_checker ~long:"crashcontext" @@ -884,6 +884,10 @@ and clang_ignore_regex = around missing generated files." +and class_loads_roots = + CLOpt.mk_string_list ~long:"class-loads-roots" "Report class loads of this list of Java methods" + + and classpath = CLOpt.mk_string_opt ~long:"classpath" "Specify the Java classpath" and compilation_database = @@ -2514,6 +2518,8 @@ and classpath = !classpath and class_loads = !class_loads +and class_loads_roots = String.Set.of_list !class_loads_roots + and compute_analytics = !compute_analytics and continue_capture = !continue diff --git a/infer/src/base/Config.mli b/infer/src/base/Config.mli index 8c3451d15..f9fd2ec3b 100644 --- a/infer/src/base/Config.mli +++ b/infer/src/base/Config.mli @@ -71,6 +71,8 @@ val classpath : string option val class_loads : bool +val class_loads_roots : String.Set.t + val costs_report_json : string val cpp_extra_include_dir : string diff --git a/infer/src/base/IssueType.ml b/infer/src/base/IssueType.ml index 5483f0fad..995a58da7 100644 --- a/infer/src/base/IssueType.ml +++ b/infer/src/base/IssueType.ml @@ -136,6 +136,8 @@ let checkers_printf_args = from_string "CHECKERS_PRINTF_ARGS" let class_cast_exception = from_string ~enabled:false "CLASS_CAST_EXCEPTION" +let class_load = from_string "CLASS_LOAD" + let codequery = from_string "Codequery" let comparing_floats_for_equality = from_string "COMPARING_FLOAT_FOR_EQUALITY" diff --git a/infer/src/base/IssueType.mli b/infer/src/base/IssueType.mli index f672723d8..7f4ade9bf 100644 --- a/infer/src/base/IssueType.mli +++ b/infer/src/base/IssueType.mli @@ -84,6 +84,8 @@ val checkers_printf_args : t val class_cast_exception : t +val class_load : t + val codequery : t val comparing_floats_for_equality : t diff --git a/infer/src/concurrency/classLoads.ml b/infer/src/concurrency/classLoads.ml index 3e8639dd8..b7729e28f 100644 --- a/infer/src/concurrency/classLoads.ml +++ b/infer/src/concurrency/classLoads.ml @@ -23,7 +23,23 @@ let exec_instr pdesc astate _ (instr : Sil.instr) = astate +let report_loads proc_desc summary astate = + let report_load ({ClassLoadsDomain.Event.loc} as event) = + let ltr = ClassLoadsDomain.Event.make_loc_trace event in + Reporting.log_warning summary ~loc ~ltr IssueType.class_load "Class load" + in + let pname = Procdesc.get_proc_name proc_desc in + ClassLoadsDomain.get_java_class pname + |> Option.iter ~f:(fun clazz -> + let method_strname = Typ.Procname.get_method pname in + let fullname = clazz ^ "." ^ method_strname in + (* Logging.debug_dev "Pname = %s" method_strname ; *) + if String.Set.mem Config.class_loads_roots fullname then + ClassLoadsDomain.iter report_load astate ) + + let analyze_procedure {Callbacks.proc_desc; summary} = let init = ClassLoadsDomain.empty in let post = Procdesc.fold_instrs proc_desc ~init ~f:(exec_instr proc_desc) in + report_loads proc_desc summary post ; Payload.update_summary post summary diff --git a/infer/src/concurrency/classLoadsDomain.ml b/infer/src/concurrency/classLoadsDomain.ml index 39bf252a4..da121dfe7 100644 --- a/infer/src/concurrency/classLoadsDomain.ml +++ b/infer/src/concurrency/classLoadsDomain.ml @@ -21,16 +21,20 @@ let add ({Event.trace} as x) astate = let union xs ys = fold add xs ys -let integrate_summary callee_pname loc astate callee_summary = - match callee_pname with +let get_java_class = function | Typ.Procname.Java java_pname -> - let clazz = Typ.Procname.Java.get_class_name java_pname in - let new_event = Event.make clazz loc in - let callsite = CallSite.make callee_pname loc in - let summary = with_callsite callee_summary callsite in - add new_event astate |> union summary + Some (Typ.Procname.Java.get_class_name java_pname) | _ -> - astate + None + + +let integrate_summary callee_pname loc astate callee_summary = + get_java_class callee_pname + |> Option.value_map ~default:astate ~f:(fun clazz -> + let new_event = Event.make clazz loc in + let callsite = CallSite.make callee_pname loc in + let summary = with_callsite callee_summary callsite in + add new_event astate |> union summary ) type summary = astate diff --git a/infer/src/concurrency/classLoadsDomain.mli b/infer/src/concurrency/classLoadsDomain.mli index 83178de83..b8c7995aa 100644 --- a/infer/src/concurrency/classLoadsDomain.mli +++ b/infer/src/concurrency/classLoadsDomain.mli @@ -6,9 +6,16 @@ *) open! IStd module F = Format +module ClassLoad = String + +val get_java_class : Typ.Procname.t -> string option + +module Event : ExplicitTrace.TraceElem with type elem_t = ClassLoad.t include AbstractDomain.WithBottom +include PrettyPrintable.PPSet with type t = astate and type elt = Event.t + type summary = astate val pp_summary : F.formatter -> summary -> unit diff --git a/infer/tests/codetoanalyze/java/classloads/Basic.java b/infer/tests/codetoanalyze/java/classloads/Basic.java new file mode 100644 index 000000000..9b7134df9 --- /dev/null +++ b/infer/tests/codetoanalyze/java/classloads/Basic.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2018-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +class Basic { + void foo_report(Other o) { + o.bar(); + } + + void baz_no_report(Another a) { + a.baz(); + } +} + +class Other { + void bar() {} +} + +class Another { + void baz() {} +} diff --git a/infer/tests/codetoanalyze/java/classloads/Makefile b/infer/tests/codetoanalyze/java/classloads/Makefile new file mode 100644 index 000000000..9837fa64e --- /dev/null +++ b/infer/tests/codetoanalyze/java/classloads/Makefile @@ -0,0 +1,12 @@ +# Copyright (c) 2018-present, Facebook, Inc. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +TESTS_DIR = ../../.. + +INFER_OPTIONS = --class-loads-only --class-loads-roots "Basic.foo_report" --debug-exceptions +INFERPRINT_OPTIONS = --issues-tests +SOURCES = $(wildcard *.java) + +include $(TESTS_DIR)/javac.make diff --git a/infer/tests/codetoanalyze/java/classloads/issues.exp b/infer/tests/codetoanalyze/java/classloads/issues.exp new file mode 100644 index 000000000..491b62b21 --- /dev/null +++ b/infer/tests/codetoanalyze/java/classloads/issues.exp @@ -0,0 +1 @@ +codetoanalyze/java/classloads/Basic.java, Basic.foo_report(Other):void, 1, CLASS_LOAD, no_bucket, WARNING, [Other]