[classloads] remove dead analyser

Summary: As per title

Reviewed By: jvillard

Differential Revision: D22019146

fbshipit-source-id: 3837993e5
master
Nikos Gorogiannis 5 years ago committed by Facebook GitHub Bot
parent 4bbe5a064b
commit 23c1b4f960

2
.gitignore vendored

@ -50,8 +50,6 @@ duplicates.txt
/infer/tests/build_systems/incremental_analysis_cost_change/src /infer/tests/build_systems/incremental_analysis_cost_change/src
/infer/tests/build_systems/incremental_analysis_add_procedure/src /infer/tests/build_systems/incremental_analysis_add_procedure/src
/infer/tests/build_systems/java_test_determinator/*.test /infer/tests/build_systems/java_test_determinator/*.test
/infer/tests/codetoanalyze/java/classloads/*.loads
/infer/tests/codetoanalyze/java/classloads/loads.exp
/_release /_release
/infer-source /infer-source

@ -157,7 +157,6 @@ DIRECT_TESTS += \
java_biabduction \ java_biabduction \
java_bufferoverrun \ java_bufferoverrun \
java_checkers \ java_checkers \
java_classloads \
java_nullsafe \ java_nullsafe \
java_hoisting \ java_hoisting \
java_hoistingExpensive \ java_hoistingExpensive \

@ -47,14 +47,6 @@ OPTIONS
reactive analysis should start. Source files should be specified reactive analysis should start. Source files should be specified
relative to project root or be absolute relative to project root or be absolute
--class-loads
Activates: checker class-loads: Compute set of Java classes
loaded. (Conversely: --no-class-loads)
--class-loads-only
Activates: Enable class-loads and disable all other checkers
(Conversely: --no-class-loads-only)
--continue-analysis --continue-analysis
Activates: Continue the analysis after more targets are captured Activates: Continue the analysis after more targets are captured
by --continue. The other analysis options should be given the same by --continue. The other analysis options should be given the same

@ -228,14 +228,6 @@ OPTIONS
arrays) is not done element by element but using a builtin arrays) is not done element by element but using a builtin
function that each analysis has to model. See also infer-analyze(1) and infer-capture(1). function that each analysis has to model. See also infer-analyze(1) and infer-capture(1).
--class-loads
Activates: checker class-loads: Compute set of Java classes
loaded. (Conversely: --no-class-loads) 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 --compilation-database +path
File that contain compilation commands (can be specified multiple File that contain compilation commands (can be specified multiple
times) See also infer-capture(1). times) See also infer-capture(1).
@ -394,7 +386,6 @@ OPTIONS
CHECKERS_IMMUTABLE_CAST (enabled by default), CHECKERS_IMMUTABLE_CAST (enabled by default),
CHECKERS_PRINTF_ARGS (enabled by default), CHECKERS_PRINTF_ARGS (enabled by default),
CLASS_CAST_EXCEPTION (disabled by default), CLASS_CAST_EXCEPTION (disabled by default),
CLASS_LOAD (enabled by default),
COMPONENT_FACTORY_FUNCTION (enabled by default), COMPONENT_FACTORY_FUNCTION (enabled by default),
COMPONENT_FILE_CYCLOMATIC_COMPLEXITY (enabled by default), COMPONENT_FILE_CYCLOMATIC_COMPLEXITY (enabled by default),
COMPONENT_FILE_LINE_COUNT (disabled by default), COMPONENT_FILE_LINE_COUNT (disabled by default),
@ -1330,12 +1321,6 @@ INTERNAL OPTIONS
--clang-libcxx-include-to-override-regex-reset --clang-libcxx-include-to-override-regex-reset
Cancel the effect of --clang-libcxx-include-to-override-regex. Cancel the effect of --clang-libcxx-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 --classpath string
Specify the Java classpath Specify the Java classpath

@ -116,7 +116,6 @@ OPTIONS
CHECKERS_IMMUTABLE_CAST (enabled by default), CHECKERS_IMMUTABLE_CAST (enabled by default),
CHECKERS_PRINTF_ARGS (enabled by default), CHECKERS_PRINTF_ARGS (enabled by default),
CLASS_CAST_EXCEPTION (disabled by default), CLASS_CAST_EXCEPTION (disabled by default),
CLASS_LOAD (enabled by default),
COMPONENT_FACTORY_FUNCTION (enabled by default), COMPONENT_FACTORY_FUNCTION (enabled by default),
COMPONENT_FILE_CYCLOMATIC_COMPLEXITY (enabled by default), COMPONENT_FILE_CYCLOMATIC_COMPLEXITY (enabled by default),
COMPONENT_FILE_LINE_COUNT (disabled by default), COMPONENT_FILE_LINE_COUNT (disabled by default),

@ -228,14 +228,6 @@ OPTIONS
arrays) is not done element by element but using a builtin arrays) is not done element by element but using a builtin
function that each analysis has to model. See also infer-analyze(1) and infer-capture(1). function that each analysis has to model. See also infer-analyze(1) and infer-capture(1).
--class-loads
Activates: checker class-loads: Compute set of Java classes
loaded. (Conversely: --no-class-loads) 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 --compilation-database +path
File that contain compilation commands (can be specified multiple File that contain compilation commands (can be specified multiple
times) See also infer-capture(1). times) See also infer-capture(1).
@ -394,7 +386,6 @@ OPTIONS
CHECKERS_IMMUTABLE_CAST (enabled by default), CHECKERS_IMMUTABLE_CAST (enabled by default),
CHECKERS_PRINTF_ARGS (enabled by default), CHECKERS_PRINTF_ARGS (enabled by default),
CLASS_CAST_EXCEPTION (disabled by default), CLASS_CAST_EXCEPTION (disabled by default),
CLASS_LOAD (enabled by default),
COMPONENT_FACTORY_FUNCTION (enabled by default), COMPONENT_FACTORY_FUNCTION (enabled by default),
COMPONENT_FILE_CYCLOMATIC_COMPLEXITY (enabled by default), COMPONENT_FILE_CYCLOMATIC_COMPLEXITY (enabled by default),
COMPONENT_FILE_LINE_COUNT (disabled by default), COMPONENT_FILE_LINE_COUNT (disabled by default),

@ -13,7 +13,6 @@ type t =
; biabduction: BiabductionSummary.t option ; biabduction: BiabductionSummary.t option
; buffer_overrun_analysis: BufferOverrunAnalysisSummary.t option ; buffer_overrun_analysis: BufferOverrunAnalysisSummary.t option
; buffer_overrun_checker: BufferOverrunCheckerSummary.t option ; buffer_overrun_checker: BufferOverrunCheckerSummary.t option
; class_loads: ClassLoadsDomain.summary option
; cost: CostDomain.summary option ; cost: CostDomain.summary option
; lab_resource_leaks: ResourceLeakDomain.summary option ; lab_resource_leaks: ResourceLeakDomain.summary option
; litho_required_props: LithoDomain.summary option ; litho_required_props: LithoDomain.summary option
@ -39,7 +38,6 @@ let fields =
~biabduction:(fun f -> mk_pe f "Biabduction" BiabductionSummary.pp) ~biabduction:(fun f -> mk_pe f "Biabduction" BiabductionSummary.pp)
~buffer_overrun_analysis:(fun f -> mk f "BufferOverrunAnalysis" BufferOverrunAnalysisSummary.pp) ~buffer_overrun_analysis:(fun f -> mk f "BufferOverrunAnalysis" BufferOverrunAnalysisSummary.pp)
~buffer_overrun_checker:(fun f -> mk f "BufferOverrunChecker" BufferOverrunCheckerSummary.pp) ~buffer_overrun_checker:(fun f -> mk f "BufferOverrunChecker" BufferOverrunCheckerSummary.pp)
~class_loads:(fun f -> mk f "ClassLoads" ClassLoadsDomain.pp_summary)
~cost:(fun f -> mk f "Cost" CostDomain.pp_summary) ~cost:(fun f -> mk f "Cost" CostDomain.pp_summary)
~litho_required_props:(fun f -> mk f "Litho Required Props" LithoDomain.pp_summary) ~litho_required_props:(fun f -> mk f "Litho Required Props" LithoDomain.pp_summary)
~pulse:(fun f -> mk f "Pulse" PulseSummary.pp) ~pulse:(fun f -> mk f "Pulse" PulseSummary.pp)
@ -63,7 +61,6 @@ let empty =
; biabduction= None ; biabduction= None
; buffer_overrun_analysis= None ; buffer_overrun_analysis= None
; buffer_overrun_checker= None ; buffer_overrun_checker= None
; class_loads= None
; cost= None ; cost= None
; lab_resource_leaks= None ; lab_resource_leaks= None
; litho_required_props= None ; litho_required_props= None

@ -17,7 +17,6 @@ include sig
; biabduction: BiabductionSummary.t option ; biabduction: BiabductionSummary.t option
; buffer_overrun_analysis: BufferOverrunAnalysisSummary.t option ; buffer_overrun_analysis: BufferOverrunAnalysisSummary.t option
; buffer_overrun_checker: BufferOverrunCheckerSummary.t option ; buffer_overrun_checker: BufferOverrunCheckerSummary.t option
; class_loads: ClassLoadsDomain.summary option
; cost: CostDomain.summary option ; cost: CostDomain.summary option
; lab_resource_leaks: ResourceLeakDomain.summary option ; lab_resource_leaks: ResourceLeakDomain.summary option
; litho_required_props: LithoDomain.summary option ; litho_required_props: LithoDomain.summary option

@ -77,9 +77,6 @@ let all_checkers =
(* The order of the list is important for those checkers that depend on other checkers having run (* The order of the list is important for those checkers that depend on other checkers having run
before them. *) before them. *)
[ {checker= SelfInBlock; callbacks= [(intraprocedural SelfInBlock.checker, Clang)]} [ {checker= SelfInBlock; callbacks= [(intraprocedural SelfInBlock.checker, Clang)]}
; { checker= ClassLoads
; callbacks= [(interprocedural Payloads.Fields.class_loads ClassLoads.analyze_procedure, Java)]
}
; { checker= Purity ; { checker= Purity
; callbacks= ; callbacks=
(let purity = (let purity =

@ -13,7 +13,6 @@ type t =
| Biabduction | Biabduction
| BufferOverrunAnalysis | BufferOverrunAnalysis
| BufferOverrunChecker | BufferOverrunChecker
| ClassLoads
| Cost | Cost
| Eradicate | Eradicate
| FragmentRetainsView | FragmentRetainsView
@ -120,18 +119,6 @@ let config_unsafe checker =
; cli_flags= Some {deprecated= []; show_in_help= true} ; cli_flags= Some {deprecated= []; show_in_help= true}
; enabled_by_default= false ; enabled_by_default= false
; activates= [BufferOverrunAnalysis] } ; activates= [BufferOverrunAnalysis] }
| ClassLoads ->
{ id= "class-loads"
; kind=
UserFacingDeprecated
{ title= "Class loading analysis"
; markdown_body= ""
; deprecation_message= "Unmaintained prototype." }
; support= supports_java
; short_documentation= "Compute set of Java classes loaded."
; cli_flags= Some {deprecated= []; show_in_help= true}
; enabled_by_default= false
; activates= [] }
| Cost -> | Cost ->
{ id= "cost" { id= "cost"
; kind= UserFacing {title= "Cost: Runtime Complexity Analysis"; markdown_body= ""} ; kind= UserFacing {title= "Cost: Runtime Complexity Analysis"; markdown_body= ""}

@ -12,7 +12,6 @@ type t =
| Biabduction | Biabduction
| BufferOverrunAnalysis | BufferOverrunAnalysis
| BufferOverrunChecker | BufferOverrunChecker
| ClassLoads
| Cost | Cost
| Eradicate | Eradicate
| FragmentRetainsView | FragmentRetainsView

@ -889,10 +889,6 @@ and clang_libcxx_include_to_override_regex =
$(b,-I /path/to/infer/facebook-clang-plugins/clang/install/include/c++/v1)." $(b,-I /path/to/infer/facebook-clang-plugins/clang/install/include/c++/v1)."
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 classpath = CLOpt.mk_string_opt ~long:"classpath" "Specify the Java classpath"
and compilation_database = and compilation_database =
@ -2708,8 +2704,6 @@ and clang_libcxx_include_to_override_regex = !clang_libcxx_include_to_override_r
and classpath = !classpath and classpath = !classpath
and class_loads_roots = String.Set.of_list !class_loads_roots
and compute_analytics = !compute_analytics and compute_analytics = !compute_analytics
and continue_analysis = !continue_analysis and continue_analysis = !continue_analysis

@ -226,8 +226,6 @@ val clang_idirafter_to_override_regex : Str.regexp option
val clang_libcxx_include_to_override_regex : string option val clang_libcxx_include_to_override_regex : string option
val class_loads_roots : String.Set.t
val command : InferCommand.t val command : InferCommand.t
val compute_analytics : bool val compute_analytics : bool

@ -331,8 +331,6 @@ let class_cast_exception =
Biabduction Biabduction
let class_load = register_from_string ~id:"CLASS_LOAD" Warning ClassLoads
let component_factory_function = let component_factory_function =
register_from_string ~id:"COMPONENT_FACTORY_FUNCTION" Advice Linters register_from_string ~id:"COMPONENT_FACTORY_FUNCTION" Advice Linters
~user_documentation:[%blob "../../documentation/issues/COMPONENT_FACTORY_FUNCTION.md"] ~user_documentation:[%blob "../../documentation/issues/COMPONENT_FACTORY_FUNCTION.md"]

@ -139,8 +139,6 @@ val checkers_printf_args : t
val class_cast_exception : t val class_cast_exception : t
val class_load : t
val complexity_increase : kind:CostKind.t -> is_on_ui_thread:bool -> t val complexity_increase : kind:CostKind.t -> is_on_ui_thread:bool -> t
val component_factory_function : t val component_factory_function : t

@ -1,138 +0,0 @@
(*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*)
open! IStd
module L = Logging
(* Sources: Java Virtual Machine Specification
- Chapter 5. Loading, Linking and Initializing
- Chapter 6. The Java Virtual Machine Instruction Set
*)
(* TODO
- catch / throw with exception classes
*)
let do_call {InterproceduralAnalysis.analyze_dependency} callee loc init =
analyze_dependency callee
|> Option.fold ~init ~f:(fun acc (_, summary) ->
ClassLoadsDomain.integrate_summary callee loc acc summary )
(** fully load a class given the typename *)
let rec load_class ({InterproceduralAnalysis.tenv} as analysis_data) loc astate class_name =
(* don't bother if class is already loaded *)
if ClassLoadsDomain.mem_typename class_name astate then astate
else
(* load the class itself *)
let astate1 = ClassLoadsDomain.add_typename loc astate class_name in
(* load classes referenced by the class initializer *)
let astate2 =
let class_initializer = Procname.(Java (Java.get_class_initializer class_name)) in
(* NB may recurse if we are in class init but the shortcircuiting above makes it a no-op *)
do_call analysis_data class_initializer loc astate1
in
(* finally, recursively load all superclasses *)
Tenv.lookup tenv class_name
|> Option.value_map ~default:[] ~f:(fun tstruct -> tstruct.Struct.supers)
|> List.fold ~init:astate2 ~f:(load_class analysis_data loc)
let load_type analysis_data loc (typ : Typ.t) astate =
match typ with
| {desc= Tstruct name} | {desc= Tptr ({desc= Tstruct name}, _)} ->
load_class analysis_data loc astate name
| _ ->
astate
let rec load_array analysis_data loc (typ : Typ.t) astate =
match typ with
| {desc= Tarray {elt}} ->
load_array analysis_data loc elt astate
| _ ->
load_type analysis_data loc typ astate
let rec add_loads_of_exp analysis_data loc (exp : Exp.t) astate =
match exp with
| Const (Cclass class_ident) ->
(* [X.class] expressions *)
let class_str = Ident.name_to_string class_ident |> JavaClassName.from_string in
let class_name = Typ.JavaClass class_str in
load_class analysis_data loc astate class_name
| Sizeof {typ= {desc= Tarray {elt}}} ->
(* anewarray / multinewarray *)
load_array analysis_data loc elt astate
| Cast (_, e) | UnOp (_, e, _) | Exn e ->
(* NB Cast is only used for primitive types *)
add_loads_of_exp analysis_data loc e astate
| BinOp (_, e1, e2) ->
add_loads_of_exp analysis_data loc e1 astate |> add_loads_of_exp analysis_data loc e2
| Lfield (e, _, typ') ->
(* getfield / getstatic / putfield / putstatic *)
load_type analysis_data loc typ' astate |> add_loads_of_exp analysis_data loc e
| Var _ | Const _ | Closure _ | Sizeof _ | Lindex _ | Lvar _ ->
astate
let exec_call analysis_data callee args loc astate =
match args with
| [_; (Exp.Sizeof {typ}, _)] when Procname.equal callee BuiltinDecl.__instanceof ->
(* this matches downcasts/instanceof and exception handlers *)
load_type analysis_data loc typ astate
| _ ->
(* invokeinterface / invokespecial / invokestatic / invokevirtual / new *)
List.fold args ~init:astate ~f:(fun acc (exp, _) ->
add_loads_of_exp analysis_data loc exp acc )
|> do_call analysis_data callee loc
let exec_instr analysis_data astate _ (instr : Sil.instr) =
match instr with
| Call (_, Const (Cfun callee), args, loc, _) ->
exec_call analysis_data callee args loc astate
| Load {e= exp; loc} | Prune (exp, loc, _, _) ->
(* NB the java frontend seems to always translate complex guards into a sequence of
instructions plus a prune on logical vars only. So the below is only for completeness. *)
add_loads_of_exp analysis_data loc exp astate
| Store {e1; e2; loc} ->
add_loads_of_exp analysis_data loc e1 astate |> add_loads_of_exp analysis_data loc e2
| _ ->
astate
let report_loads {InterproceduralAnalysis.proc_desc; err_log} astate =
let report_load ({ClassLoadsDomain.Event.loc; elem} as event) =
if String.is_prefix ~prefix:"java." elem then ()
else
let ltr = ClassLoadsDomain.Event.make_loc_trace event in
let msg = Format.asprintf "Class %s loaded" elem in
Reporting.log_issue proc_desc err_log ~loc ~ltr ClassLoads IssueType.class_load msg
in
let pname = Procdesc.get_proc_name proc_desc in
Procname.get_class_name pname
|> Option.iter ~f:(fun clazz ->
let method_strname = Procname.get_method pname in
let fullname = clazz ^ "." ^ method_strname in
if String.Set.mem Config.class_loads_roots fullname then
ClassLoadsDomain.iter report_load astate )
let analyze_procedure ({InterproceduralAnalysis.proc_desc} as analysis_data) =
let proc_name = Procdesc.get_proc_name proc_desc in
L.debug Analysis Verbose "CL: ANALYZING %a@." Procname.pp proc_name ;
let loc = Procdesc.get_loc proc_desc in
(* load the method's class *)
let init =
Procname.get_class_type_name proc_name
|> Option.fold ~init:ClassLoadsDomain.bottom ~f:(load_class analysis_data loc)
in
let post = Procdesc.fold_instrs proc_desc ~init ~f:(exec_instr analysis_data) in
report_loads analysis_data post ;
L.debug Analysis Verbose "CL: FINISHED ANALYZING %a@." Procname.pp proc_name ;
Some post

@ -1,11 +0,0 @@
(*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*)
open! IStd
val analyze_procedure :
ClassLoadsDomain.summary InterproceduralAnalysis.t -> ClassLoadsDomain.summary option

@ -1,56 +0,0 @@
(*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*)
open! IStd
module F = Format
module L = Logging
module ClassLoad = struct
include String
let describe = pp
end
module Event =
ExplicitTrace.MakeTraceElemModuloLocation (ClassLoad) (ExplicitTrace.DefaultCallPrinter)
include Event.FiniteSet
let add ({Event.trace} as x) astate =
match find_opt x astate with
| None ->
add x astate
| Some ({Event.trace= trace'} as x') ->
if Int.( <= ) (List.length trace') (List.length trace) then astate
else remove x' astate |> add x
let union xs ys = fold add xs ys
let add_string loc astate clazz =
L.debug Analysis Verbose "CL: LOADING class %s@." clazz ;
let new_event = Event.make clazz loc in
add new_event astate
let mem_typename name astate =
let str_name = Typ.Name.name name in
(* comparison of elements is only over the string component so fake the rest *)
let fake_event = Event.make str_name Location.dummy in
mem fake_event astate
let add_typename loc astate name = Typ.Name.name name |> add_string loc astate
let integrate_summary callee_pname loc astate callee_summary =
L.debug Analysis Verbose "CL: ADDING SUMMARY OF %a@." Procname.pp callee_pname ;
let callsite = CallSite.make callee_pname loc in
let summary = with_callsite callee_summary callsite in
union astate summary
type summary = t
let pp_summary = pp

@ -1,26 +0,0 @@
(*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*)
open! IStd
module F = Format
module ClassLoad : ExplicitTrace.Element with type t = string
module Event : ExplicitTrace.TraceElem with type elem_t = ClassLoad.t
include AbstractDomain.WithBottom
type summary = t
val pp_summary : F.formatter -> summary -> unit
val mem_typename : Typ.Name.t -> t -> bool
val add_typename : Location.t -> t -> Typ.Name.t -> t
val integrate_summary : Procname.t -> Location.t -> t -> summary -> t
val iter : (Event.t -> unit) -> t -> unit

@ -1,40 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
class Arrays {
static ArraysB[] arrayB = new ArraysB[10];
static ArraysC[] arrayC = ArraysD.arrayC;
public static void main(String args[]) {
ArraysA[] arrayA = new ArraysA[10];
System.out.println(ArraysF.foo()[0]);
ArraysG[][] arrayG = new ArraysG[10][10];
}
}
class ArraysA {}
class ArraysB {}
class ArraysC {}
class ArraysD {
static ArraysC[] arrayC = new ArraysC[10];
}
class ArraysE {}
class ArraysF {
static ArraysE[] foo() {
return new ArraysE[10];
}
}
class ArraysG {}

@ -1,14 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
class Basic {
public static void main(String args[]) {
new BasicObj();
}
}
class BasicObj {}

@ -1,32 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
class Casts {
// there is no way to test this dynamically, as to avoid an exception
// we must first create a CastsC object. So this is more for documenting.
public static void main(String args[]) {
CastsA.downcast(new CastsC());
}
}
class CastsA {
static CastsC downcast(CastsB c) {
return (CastsC) c;
}
static boolean checkclass(CastsD d) {
return d instanceof CastsE;
}
}
class CastsB {}
class CastsC extends CastsB {}
class CastsD {}
class CastsE extends CastsD {}

@ -1,21 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
class Catch {
public static void main(String args[]) {
try {
foo();
} catch (CatchA a) {
}
}
static void foo() throws CatchA {}
}
class CatchA extends Exception {
static final long serialVersionUID = 0L;
}

@ -1,19 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
class Const {
public static void main(String args[]) {
synchronized (ConstA.class) {
}
java.lang.Class<ConstB> b = ConstB.class;
}
}
class ConstA {}
class ConstB {}

@ -1,41 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
class Fields {
FieldsA a;
Fields() {
a = new FieldsA();
}
void foo() {
System.out.println(a.b.c);
}
public static void main(String args[]) {
Fields f = new Fields();
f.foo();
}
}
class FieldsA {
FieldsA() {
b = new FieldsB();
}
FieldsB b;
}
class FieldsB {
FieldsB() {
c = null;
}
FieldsCNoLoad c;
}
class FieldsCNoLoad {}

@ -1,70 +0,0 @@
# Copyright (c) Facebook, Inc. and its affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
# Convention: each Java file must have a single [main] method in the eponymous public class
# This is the root for class loads analysis, and the one executed in the JVM to log loads.
# There is no .exp file committed, the loads are generated by JVM during testing.
TESTS_DIR = ../../..
INFERPRINT_OPTIONS = --issues-tests
SOURCES = $(wildcard *.java)
LOADS = $(patsubst %.java,%.loads,$(SOURCES))
OBJECTS = $(patsubst %.java,%.class,$(SOURCES))
CLASS_LOADS_OPT = $(patsubst %.java,--class-loads-roots %.main,$(SOURCES))
INFER_OPTIONS = --class-loads-only $(CLASS_LOADS_OPT) --debug-exceptions
CLEAN_EXTRA = *.class *.loads loads.exp loads.exp.test
include $(TESTS_DIR)/java.make
INFER_OUT ?= infer-out$(TEST_SUFFIX)
include $(TESTS_DIR)/base.make
.PHONY: clean
clean:
$(REMOVE_DIR) codetoanalyze com issues.exp.test$(TEST_SUFFIX) $(CLEAN_EXTRA)
ifneq ($(INFER_OUT),.)
$(REMOVE_DIR) $(INFER_OUT)
endif
PROJECT_ROOT ?= $(TESTS_DIR)
issues.exp.test$(TEST_SUFFIX): $(INFER_OUT)/report.json $(INFER_BIN)
$(QUIET)$(INFER_BIN) report -q --results-dir $(<D) \
$(INFERPRINT_OPTIONS) $@
infer-out/report.json: $(JAVA_DEPS) $(SOURCES) $(MAKEFILE_LIST)
$(QUIET)$(call silent_on_success,Testing infer/java in $(TEST_REL_DIR),\
$(INFER_BIN) --project-root $(PROJECT_ROOT) \
$(INFER_OPTIONS) -- \
$(JAVAC) -cp $(CLASSPATH) $(SOURCES))
%.loads: %.class
ifeq ($(JDK11_ENABLED),yes)
$(QUIET)java -verbose:class $* | grep "\[info\]\[class,load\]" | cut -f2 -d' ' | grep -vE "^(java|sun|jdk|opened:)" > $@
else
$(QUIET)java -verbose:class $* | grep "^\[Loaded" | cut -f2 -d' ' | grep -vE "^(java|sun)" > $@
endif
# infer compiles as well as analyses; dependency ensures class files are generated
$(OBJECTS): issues.exp.test$(TEST_SUFFIX)
loads.exp: $(LOADS)
$(QUIET)for F in $(LOADS) ; do sed -e "s#^#$(TEST_REL_DIR)/$${F%.*}.java, #" $$F ; done | sort > loads.exp
loads.exp.test: issues.exp.test$(TEST_SUFFIX)
$(QUIET)cat $< | sed 's/^\([^,]*\),.*[,\[]\([^,]*\)\]$$/\1, \2/' | sort > $@
.PHONY: test
test: loads.exp loads.exp.test
$(QUIET)cd $(TESTS_DIR) && \
$(call check_no_diff,$(TEST_REL_DIR)/loads.exp,$(TEST_REL_DIR)/loads.exp.test)
.PHONY: replace
replace:
@:

@ -1,22 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
class Prune {
public static void main(String args[]) {
if (PruneA.f == 0) {
System.out.println(PruneB.g < 0);
}
}
}
class PruneA {
static int f;
}
class PruneB {
static int g;
}

@ -1,32 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
class Static {
// this loads StaticA
static StaticA s = new StaticA();
public static void main(String args[]) {
// this loads StaticD
System.out.println(StaticD.static_data);
}
}
class StaticA {
// this loads StaticB
static StaticB b = new StaticB();
}
class StaticB {
// no load here
static StaticCNoLoad c = null;
}
class StaticCNoLoad {}
class StaticD {
static int static_data = 5;
}

@ -1,28 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
class Super {
public static void main(String args[]) {
// this loads SuperB and SuperA
System.out.println(SuperB.static_data);
// this loads SuperC and SuperD
SuperD.foo();
}
}
class SuperA {}
class SuperB extends SuperA {
static int static_data = 5;
}
class SuperC {}
class SuperD extends SuperC {
public static void foo() {}
}

@ -1,18 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
class Unique {
public static void main(String args[]) {
// two loads for the same class with distinct locations and traces should be merged into one
UniqueObj u = new UniqueObj();
u.foo();
}
}
class UniqueObj {
void foo() {}
}
Loading…
Cancel
Save