[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
master
Nikos Gorogiannis 6 years ago committed by Facebook Github Bot
parent 497720386e
commit ea7b185b6b

@ -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

@ -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,

@ -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

@ -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

@ -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

@ -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

@ -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"

@ -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

@ -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

@ -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
Some (Typ.Procname.Java.get_class_name java_pname)
| _ ->
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
| _ ->
astate
add new_event astate |> union summary )
type summary = astate

@ -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

@ -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() {}
}

@ -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

@ -0,0 +1 @@
codetoanalyze/java/classloads/Basic.java, Basic.foo_report(Other):void, 1, CLASS_LOAD, no_bucket, WARNING, [Other]
Loading…
Cancel
Save