[infer][ondemand] run all the registered checkers in sequence

Summary: Run all the checkers one after each other, which allows the Infer AI framework to run several checkers together, including the possibility for them to collaborate.

Reviewed By: sblackshear

Differential Revision: D4621838

fbshipit-source-id: e264d67
master
Jeremy Dubreil 8 years ago committed by Facebook Github Bot
parent 34106a2056
commit e23b04180e

@ -89,32 +89,31 @@ let iterate_procedure_callbacks exe_env caller_pname =
Specs.add_summary proc_name summary;
summary in
let initial_summary = reset_summary caller_pname in
match get_procedure_definition exe_env caller_pname with
| None -> ()
| Some (idenv, tenv, proc_name, proc_desc, _) ->
ignore
(List.fold
~init:(reset_summary proc_name)
~f:(fun summary (language_opt, proc_callback) ->
let language_matches = match language_opt with
| Some language -> Config.equal_language language procedure_language
| None -> true in
if language_matches then
let init_time = Unix.gettimeofday () in
proc_callback
{
get_proc_desc;
get_procs_in_file;
idenv;
tenv;
summary;
proc_desc;
}
|> update_time (Unix.gettimeofday () -. init_time)
else
summary)
!procedure_callbacks);
Specs.store_summary (Specs.get_summary_unsafe "iterate_procedure_callbacks" proc_name)
| None -> initial_summary
| Some (idenv, tenv, _, proc_desc, _) ->
List.fold
~init:initial_summary
~f:(fun summary (language_opt, proc_callback) ->
let language_matches = match language_opt with
| Some language -> Config.equal_language language procedure_language
| None -> true in
if language_matches then
let init_time = Unix.gettimeofday () in
proc_callback
{
get_proc_desc;
get_procs_in_file;
idenv;
tenv;
summary;
proc_desc;
}
|> update_time (Unix.gettimeofday () -. init_time)
else
summary)
!procedure_callbacks
(** Invoke all registered cluster callbacks on a cluster of procedures. *)
@ -154,10 +153,26 @@ let iterate_callbacks call_graph exe_env =
(* Make sure summaries exists. *)
List.iter ~f:(fun p -> ignore (reset_summary p)) procs_to_analyze;
(* Invoke procedure callbacks. *)
List.iter
~f:(iterate_procedure_callbacks exe_env)
procs_to_analyze;
let analyze_ondemand _ proc_desc =
let proc_name = Procdesc.get_proc_name proc_desc in
iterate_procedure_callbacks exe_env proc_name in
let callbacks = {
Ondemand.analyze_ondemand;
get_proc_desc = Exe_env.get_proc_desc exe_env
} in
(* Create and register on-demand analysis callback *)
let analyze_proc_name pname =
match Ondemand.get_proc_desc pname with
| None ->
failwithf "Could not find proc desc for %a" Typ.Procname.pp pname
| Some pdesc ->
ignore (Ondemand.analyze_proc_desc ~propagate_exceptions:true pdesc pdesc) in
Ondemand.set_callbacks callbacks;
(* Invoke procedure callbacks using on-demand anlaysis schedulling *)
List.iter ~f:analyze_proc_name procs_to_analyze;
let originally_defined_procs =
Cg.get_defined_nodes call_graph in
@ -185,6 +200,9 @@ let iterate_callbacks call_graph exe_env =
~f:(iterate_cluster_callbacks originally_defined_procs exe_env)
(cluster procs_to_analyze);
(* Unregister callbacks *)
Ondemand.unset_callbacks ();
(* Store all the summaries to disk *)
List.iter
~f:(fun pname ->

@ -159,35 +159,14 @@ end
module Interprocedural (Summ : Summary.S) = struct
let compute_and_store_post
~compute_post ~make_extras { Callbacks.get_proc_desc; proc_desc; tenv; } =
let proc_name = Procdesc.get_proc_name proc_desc in
let analyze_ondemand_ _ pdesc =
match compute_post (ProcData.make pdesc tenv (make_extras pdesc)) with
| Some post ->
Summ.write_summary (Procdesc.get_proc_name pdesc) post;
Some post
| None ->
None in
let analyze_ondemand source pdesc =
ignore (analyze_ondemand_ source pdesc);
Specs.get_summary_unsafe
"Inferprocedural.compute_and_store_post"
(Procdesc.get_proc_name pdesc) in
let callbacks =
{
Ondemand.analyze_ondemand;
get_proc_desc;
} in
if Ondemand.procedure_should_be_analyzed proc_name
then
begin
Ondemand.set_callbacks callbacks;
let post_opt = analyze_ondemand_ SourceFile.empty proc_desc in
Ondemand.unset_callbacks ();
post_opt
end
else
Summ.read_summary proc_desc proc_name
~compute_post ~make_extras { Callbacks.proc_desc; tenv; } =
match compute_post (ProcData.make proc_desc tenv (make_extras proc_desc)) with
| Some post ->
Summ.write_summary (Procdesc.get_proc_name proc_desc) post;
Some post
| None ->
None
end
module MakeWithScheduler (C : ProcCfg.S) (S : Scheduler.Make) (T : TransferFunctions.Make) =

@ -153,8 +153,8 @@ let method_has_annot annot tenv pname =
let method_overrides_annot annot tenv pname =
method_overrides (method_has_annot annot) tenv pname
let lookup_annotation_calls annot pname : CallSite.t list =
match Specs.get_summary pname with
let lookup_annotation_calls caller_pdesc annot pname : CallSite.t list =
match Ondemand.analyze_proc_name ~propagate_exceptions:false caller_pdesc pname with
| Some { Specs.payload = { Specs.calls = Some call_map; }; } ->
begin
try
@ -381,7 +381,7 @@ module Interprocedural = struct
report_annotation_stack src_annot.class_name snk_annot.class_name in
report_call_stack
(method_has_annot snk_annot tenv)
(lookup_annotation_calls snk_annot)
(lookup_annotation_calls proc_desc snk_annot)
f_report
(CallSite.make proc_name loc)
calls in

@ -39,7 +39,7 @@ module Make (H : Helper) = struct
match Specs.get_summary pname with
| Some global_summary ->
let payload = H.update_payload summary global_summary.Specs.payload in
Specs.store_summary { global_summary with payload; }
Specs.add_summary pname { global_summary with payload; }
| None ->
failwithf "Summary for %a should exist, but does not!@." Typ.Procname.pp pname

@ -405,39 +405,14 @@ module Main =
Build(EmptyExtension)
(** Eradicate checker for Java @Nullable annotations. *)
let callback_eradicate
({ Callbacks.get_proc_desc; summary } as callback_args) =
let callback_eradicate =
let checks =
{
TypeCheck.eradicate = true;
check_extension = false;
check_ret_type = [];
} in
let callbacks =
let analyze_ondemand _ pdesc =
let idenv_pname = Idenv.create pdesc in
let proc_name = Procdesc.get_proc_name pdesc in
let summary = Specs.get_summary_unsafe "Eradicate.analyze_ondemand" proc_name in
Main.callback checks
{ callback_args with
Callbacks.idenv = idenv_pname;
summary;
proc_desc = pdesc; } in
{
Ondemand.analyze_ondemand;
get_proc_desc;
} in
if Ondemand.procedure_should_be_analyzed (Specs.get_proc_name summary)
then
begin
Ondemand.set_callbacks callbacks;
let final_summary = Main.callback checks callback_args in
Ondemand.unset_callbacks ();
final_summary
end
else
summary
Main.callback checks
(** Call the given check_return_type at the end of every procedure. *)
let callback_check_return_type check_return_type callback_args =

@ -23,7 +23,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, [return from a call to void ExpensiveSubtypingExample.m4()]
codetoanalyze/java/checkers/ExpensiveSubtypingExample.java, void ExpensiveSubtypingExample.m3(), 0, CHECKERS_EXPENSIVE_OVERRIDES_UNANNOTATED, []
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()]

@ -36,10 +36,11 @@ public class Recursion {
safeRecursionCallSink(5, InferTaint.inferSecretSource());
}
public static void recursionBad(int i, Object param) {
// TODO (#16595757): Requires support for recursion in Ondemand
public static void FN_recursionBad(int i, Object param) {
if (i == 0) return;
InferTaint.inferSensitiveSink(param);
recursionBad(i - 1, InferTaint.inferSecretSource());
FN_recursionBad(i - 1, InferTaint.inferSecretSource());
}
}

@ -154,7 +154,6 @@ codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.log
codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 39, QUANDARY_TAINT_ERROR, [return from float Location.getSpeed(),call to int Log.wtf(String,String)]
codetoanalyze/java/quandary/LoggingPrivateData.java, void LoggingPrivateData.logAllSourcesBad(Location,TelephonyManager), 39, QUANDARY_TAINT_ERROR, [return from double Location.getLongitude(),call to int Log.wtf(String,String)]
codetoanalyze/java/quandary/Recursion.java, void Recursion.callSinkThenDivergeBad(), 1, QUANDARY_TAINT_ERROR, [return from Object InferTaint.inferSecretSource(),call to void Recursion.callSinkThenDiverge(Object),call to void InferTaint.inferSensitiveSink(Object)]
codetoanalyze/java/quandary/Recursion.java, void Recursion.recursionBad(int,Object), 3, QUANDARY_TAINT_ERROR, [return from Object InferTaint.inferSecretSource(),call to void Recursion.recursionBad(int,Object)]
codetoanalyze/java/quandary/Recursion.java, void Recursion.safeRecursionCallSinkBad(), 1, QUANDARY_TAINT_ERROR, [return from Object InferTaint.inferSecretSource(),call to void Recursion.safeRecursionCallSink(int,Object),call to void InferTaint.inferSensitiveSink(Object)]
codetoanalyze/java/quandary/Strings.java, void Strings.viaFormatterBad(), 3, QUANDARY_TAINT_ERROR, [return from Object InferTaint.inferSecretSource(),call to void InferTaint.inferSensitiveSink(Object)]
codetoanalyze/java/quandary/Strings.java, void Strings.viaFormatterIgnoreReturnBad(), 4, QUANDARY_TAINT_ERROR, [return from Object InferTaint.inferSecretSource(),call to void InferTaint.inferSensitiveSink(Object)]

@ -69,6 +69,6 @@ codetoanalyze/java/threadsafety/ThreadSafeExample.java, void ThreadSafeExample.c
codetoanalyze/java/threadsafety/ThreadSafeExample.java, void ThreadSafeExample.callVisibleForTestingBad(), 1, THREAD_SAFETY_VIOLATION, [call to void ThreadSafeExample.visibleForTestingNotPublicOk(),access to codetoanalyze.java.checkers.ThreadSafeExample.f]
codetoanalyze/java/threadsafety/ThreadSafeExample.java, void ThreadSafeExample.deeperTraceBad(), 1, THREAD_SAFETY_VIOLATION, [call to void ThreadSafeExample.callAssignInPrivateMethod(),call to void ThreadSafeExample.assignInPrivateMethodOk(),access to codetoanalyze.java.checkers.ThreadSafeExample.f]
codetoanalyze/java/threadsafety/ThreadSafeExample.java, void ThreadSafeExample.oddBad(), 1, THREAD_SAFETY_VIOLATION, [call to void ThreadSafeExample.evenOk(),access to codetoanalyze.java.checkers.ThreadSafeExample.f]
codetoanalyze/java/threadsafety/ThreadSafeExample.java, void ThreadSafeExample.recursiveBad(), 2, THREAD_SAFETY_VIOLATION, [call to void ThreadSafeExample.recursiveBad(),access to codetoanalyze.java.checkers.ThreadSafeExample.f]
codetoanalyze/java/threadsafety/ThreadSafeExample.java, void ThreadSafeExample.recursiveBad(), 1, THREAD_SAFETY_VIOLATION, [access to codetoanalyze.java.checkers.ThreadSafeExample.f]
codetoanalyze/java/threadsafety/ThreadSafeExample.java, void ThreadSafeExample.tsBad(), 1, THREAD_SAFETY_VIOLATION, [access to codetoanalyze.java.checkers.ThreadSafeExample.f]
codetoanalyze/java/threadsafety/ThreadSafeExample.java, void YesThreadSafeExtendsNotThreadSafeExample.subsubmethodBad(), 1, THREAD_SAFETY_VIOLATION, [access to codetoanalyze.java.checkers.YesThreadSafeExtendsNotThreadSafeExample.subsubfield]

Loading…
Cancel
Save