[nullsafe] make eradicate an Intraprocedural.t

Summary: On our way to making nullsafe its own dune library.

Reviewed By: mityal

Differential Revision: D21351454

fbshipit-source-id: a630cff95
master
Jules Villard 5 years ago committed by Facebook GitHub Bot
parent a11791d5fc
commit d8d38655b1

@ -0,0 +1,10 @@
(*
* 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
type t = {proc_desc: Procdesc.t; tenv: Tenv.t; err_log: Errlog.t}

@ -0,0 +1,12 @@
(*
* 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
(** a subset of {!InterproceduralAnalysis.t} that doesn't have any inter-procedural callbacks and
cannot read summaries *)
type t = {proc_desc: Procdesc.t; tenv: Tenv.t; err_log: Errlog.t}

@ -62,6 +62,24 @@ let dynamic_dispatch payload_field checker =
DynamicDispatch (proc_callback_of_interprocedural payload_field checker)
let proc_callback_of_intraprocedural ?payload_field checker {Callbacks.summary; exe_env} =
let result =
checker
{ IntraproceduralAnalysis.proc_desc= Summary.get_proc_desc summary
; tenv= Exe_env.get_tenv exe_env (Summary.get_proc_name summary)
; err_log= Summary.get_err_log summary }
in
match payload_field with
| None ->
summary
| Some payload_field ->
{summary with payloads= Field.fset payload_field summary.payloads result}
let intraprocedural_with_payload payload_field checker =
Procedure (proc_callback_of_intraprocedural ~payload_field checker)
type callback = callback_fun * Language.t
type checker = {name: string; active: bool; callbacks: callback list}
@ -150,7 +168,9 @@ let all_checkers =
; callbacks= [(Procedure InefficientKeysetIterator.checker, Language.Java)] }
; { name= "immutable cast"
; active= Config.is_checker_enabled ImmutableCast
; callbacks= [(Procedure ImmutableChecker.callback_check_immutable_cast, Language.Java)] }
; callbacks=
[ ( intraprocedural_with_payload Payloads.Fields.nullsafe ImmutableChecker.analyze
, Language.Java ) ] }
; { name= "fragment retains view"
; active= Config.is_checker_enabled FragmentRetainsView
; callbacks=
@ -158,7 +178,8 @@ let all_checkers =
; { name= "eradicate"
; active= Config.is_checker_enabled Eradicate
; callbacks=
[ (Procedure Eradicate.proc_callback, Language.Java)
[ ( intraprocedural_with_payload Payloads.Fields.nullsafe Eradicate.analyze_procedure
, Language.Java )
; (File {callback= Eradicate.file_callback; issue_dir= NullsafeFileIssues}, Language.Java)
] }
; { name= "buffer overrun checker"

@ -10,12 +10,6 @@ module L = Logging
module F = Format
open Dataflow
module Payload = SummaryPayload.Make (struct
type t = NullsafeSummary.t
let field = Payloads.Fields.nullsafe
end)
let callback1 tenv find_canonical_duplicate calls_this checks idenv curr_pname curr_pdesc
annotated_signature linereader proc_loc : bool * TypeState.t option =
let add_formal typestate (param_signature : AnnotatedSignature.param_signature) =
@ -106,7 +100,7 @@ let callback1 tenv find_canonical_duplicate calls_this checks idenv curr_pname c
(!calls_this, None)
let analyze_procedure tenv proc_name proc_desc calls_this checks annotated_signature linereader
let analyze_one_procedure tenv proc_name proc_desc calls_this checks annotated_signature linereader
proc_loc : unit =
let idenv = Idenv.create proc_desc in
let find_duplicate_nodes = State.mk_find_duplicate_nodes proc_desc in
@ -194,18 +188,16 @@ let find_reason_to_skip_analysis proc_name proc_desc =
(** Entry point for the nullsafe procedure-level analysis. *)
let callback checks {Callbacks.summary; exe_env} : Summary.t =
let proc_desc = Summary.get_proc_desc summary in
let analyze checks {IntraproceduralAnalysis.proc_desc; tenv} : NullsafeSummary.t option =
let proc_name = Procdesc.get_proc_name proc_desc in
L.debug Analysis Medium "Analysis of %a@\n" Procname.pp proc_name ;
match find_reason_to_skip_analysis proc_name proc_desc with
| Some reason ->
L.debug Analysis Medium "Skipping analysis: %s@\n" reason ;
summary
None
| None ->
(* start the analysis! *)
let calls_this = ref false in
let tenv = Exe_env.get_tenv exe_env proc_name in
let annotated_signature =
AnnotatedSignature.get_for_class_under_analysis tenv (Procdesc.get_attributes proc_desc)
in
@ -218,24 +210,24 @@ let callback checks {Callbacks.summary; exe_env} : Summary.t =
(* The main method - during this the actual analysis will happen and TypeErr will be populated with
issues (and some of them - reported).
*)
analyze_procedure tenv proc_name proc_desc calls_this checks annotated_signature linereader
loc ;
analyze_one_procedure tenv proc_name proc_desc calls_this checks annotated_signature
linereader loc ;
(* Collect issues that were detected during analysis and put them in summary for further processing *)
let issues = TypeErr.get_errors () |> List.map ~f:(fun (issues, _) -> issues) in
(* Report errors of "farall" class - those could not be reported during analysis phase. *)
TypeErr.report_forall_issues_and_reset
(EradicateCheckers.report_error tenv)
~nullsafe_mode:annotated_signature.nullsafe_mode proc_desc ;
Payload.update_summary NullsafeSummary.{issues} summary
Some {NullsafeSummary.issues}
let proc_callback =
let analyze_procedure analysis_data =
let checks = {TypeCheck.eradicate= true; check_ret_type= []} in
callback checks
analyze checks analysis_data
let file_callback = FileLevelAnalysis.analyze_file
let callback_check_return_type check_return_type callback_args =
let analyze_for_immutable_cast_checker check_return_type analysis_data =
let checks = {TypeCheck.eradicate= false; check_ret_type= [check_return_type]} in
callback checks callback_args
analyze checks analysis_data

@ -9,13 +9,14 @@ open! IStd
(** The main entry point for Nullsafe typechecker. *)
val proc_callback : Callbacks.proc_callback_t
val analyze_procedure : IntraproceduralAnalysis.t -> NullsafeSummary.t option
(** Proc-level callback for nullsafe. *)
val file_callback : Callbacks.file_callback_t
(** File-level callback for nullsafe. Is called after all proc-level callbacks are called and
calculated their summaries *)
val callback_check_return_type : TypeCheck.check_return_type -> Callbacks.proc_callback_t
val analyze_for_immutable_cast_checker :
TypeCheck.check_return_type -> IntraproceduralAnalysis.t -> NullsafeSummary.t option
(** For checkers that explore eradicate/nullsafe infra, but not part of nullsafe.Annot Call the
given check_return_type at the end of every procedure. *)

@ -43,6 +43,5 @@ let check_immutable_cast tenv curr_pname curr_pdesc typ_expected typ_found_opt l
()
let callback_check_immutable_cast ({Callbacks.exe_env; summary} as args) =
let tenv = Exe_env.get_tenv exe_env (Summary.get_proc_name summary) in
Eradicate.callback_check_return_type (check_immutable_cast tenv) args
let analyze ({IntraproceduralAnalysis.tenv} as analysis_data) =
Eradicate.analyze_for_immutable_cast_checker (check_immutable_cast tenv) analysis_data

@ -7,4 +7,4 @@
open! IStd
val callback_check_immutable_cast : Callbacks.proc_callback_t
val analyze : IntraproceduralAnalysis.t -> NullsafeSummary.t option

Loading…
Cancel
Save