make SelfInBlock an `intraprocedural`

Summary: Making checkers/ its own dune library.

Reviewed By: ezgicicek

Differential Revision: D21407068

fbshipit-source-id: 4f3b1c74d
master
Jules Villard 5 years ago committed by Facebook GitHub Bot
parent b6a7120b5f
commit 87f031ec38

@ -62,6 +62,14 @@ let interprocedural_file payload_field checker {Callbacks.procedures; exe_env; s
{InterproceduralAnalysis.procedures; source_file; file_exe_env= exe_env; analyze_file_dependency} {InterproceduralAnalysis.procedures; source_file; file_exe_env= exe_env; analyze_file_dependency}
let intraprocedural checker {Callbacks.summary; exe_env} =
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 } ;
summary
let intraprocedural_with_field payload_field checker {Callbacks.summary; exe_env} = let intraprocedural_with_field payload_field checker {Callbacks.summary; exe_env} =
let result = let result =
checker checker

@ -35,6 +35,10 @@ val interprocedural_file :
file-level analysis, given an inter-procedural analysis of dependencies that computes the file-level analysis, given an inter-procedural analysis of dependencies that computes the
payload type corresponding to [field] *) payload type corresponding to [field] *)
val intraprocedural : (IntraproceduralAnalysis.t -> unit) -> Callbacks.proc_callback_t
(** runs a simple intra-procedural analysis (one that doesn't need the results of the analysis on
any transitive dependencies to analyze a given procedure) *)
val intraprocedural_with_field : val intraprocedural_with_field :
(Payloads.t, 'payload option) Field.t (Payloads.t, 'payload option) Field.t
-> (IntraproceduralAnalysis.t -> 'payload option) -> (IntraproceduralAnalysis.t -> 'payload option)

@ -61,6 +61,8 @@ let file issue_dir payload_field checker =
File {callback= CallbackOfChecker.interprocedural_file payload_field checker; issue_dir} File {callback= CallbackOfChecker.interprocedural_file payload_field checker; issue_dir}
let intraprocedural checker = Procedure (CallbackOfChecker.intraprocedural checker)
let intraprocedural_with_payload payload_field checker = let intraprocedural_with_payload payload_field checker =
Procedure (CallbackOfChecker.intraprocedural_with_field payload_field checker) Procedure (CallbackOfChecker.intraprocedural_with_field payload_field checker)
@ -74,7 +76,7 @@ let all_checkers =
before them. *) before them. *)
[ { name= "Self captured in block checker" [ { name= "Self captured in block checker"
; active= Config.is_checker_enabled SelfInBlock ; active= Config.is_checker_enabled SelfInBlock
; callbacks= [(Procedure SelfInBlock.checker, Language.Clang)] } ; callbacks= [(intraprocedural SelfInBlock.checker, Language.Clang)] }
; { name= "Class loading analysis" ; { name= "Class loading analysis"
; active= Config.is_checker_enabled ClassLoads ; active= Config.is_checker_enabled ClassLoads
; callbacks= [(Procedure ClassLoads.analyze_procedure, Language.Java)] } ; callbacks= [(Procedure ClassLoads.analyze_procedure, Language.Java)] }

@ -143,7 +143,7 @@ module TransferFunctions = struct
module Domain = Domain module Domain = Domain
module CFG = ProcCfg.Normal module CFG = ProcCfg.Normal
type analysis_data = unit ProcData.t type analysis_data = IntraproceduralAnalysis.t
let pp_session_name _node fmt = F.pp_print_string fmt "SelfCapturedInBlock" let pp_session_name _node fmt = F.pp_print_string fmt "SelfCapturedInBlock"
@ -229,7 +229,7 @@ module TransferFunctions = struct
Location.compare loc1 loc2 ) Location.compare loc1 loc2 )
let report_unchecked_strongself_issues summary (domain : Domain.t) var_use var = let report_unchecked_strongself_issues attributes err_log (domain : Domain.t) var_use var =
match find_strong_var domain var with match find_strong_var domain var with
| Some ({DomainData.pvar; loc; kind}, _, strongVarElem) | Some ({DomainData.pvar; loc; kind}, _, strongVarElem)
when DomainData.is_unchecked_strong_self kind && not strongVarElem.reported -> when DomainData.is_unchecked_strong_self kind && not strongVarElem.reported ->
@ -240,7 +240,7 @@ module TransferFunctions = struct
(Pvar.pp Pp.text) pvar var_use Location.pp loc (Pvar.pp Pp.text) pvar var_use Location.pp loc
in in
let ltr = make_trace_unchecked_strongself domain in let ltr = make_trace_unchecked_strongself domain in
SummaryReporting.log_error summary ~ltr ~loc IssueType.strong_self_not_checked message ; Reporting.log_error attributes err_log ~ltr ~loc IssueType.strong_self_not_checked message ;
let strongVars = let strongVars =
StrongEqualToWeakCapturedVars.add pvar StrongEqualToWeakCapturedVars.add pvar
{strongVarElem with reported= true} {strongVarElem with reported= true}
@ -251,11 +251,12 @@ module TransferFunctions = struct
domain domain
let report_unchecked_strongself_issues_on_exps (domain : Domain.t) summary (instr : Sil.instr) = let report_unchecked_strongself_issues_on_exps attributes err_log (domain : Domain.t)
(instr : Sil.instr) =
let report_unchecked_strongself_issues_on_exp strongVars (exp : Exp.t) = let report_unchecked_strongself_issues_on_exp strongVars (exp : Exp.t) =
match exp with match exp with
| Lfield (Var var, _, _) -> | Lfield (Var var, _, _) ->
report_unchecked_strongself_issues summary domain "dereferenced" var report_unchecked_strongself_issues attributes err_log domain "dereferenced" var
| _ -> | _ ->
strongVars strongVars
in in
@ -305,9 +306,9 @@ module TransferFunctions = struct
None None
let report_unchecked_strongself_issues_on_args (domain : Domain.t) summary pname args = let report_unchecked_strongself_issues_on_args attributes err_log (domain : Domain.t) pname args =
let report_issue var = let report_issue var =
report_unchecked_strongself_issues summary domain report_unchecked_strongself_issues attributes err_log domain
(F.sprintf "passed to `%s`" (Procname.to_simplified_string pname)) (F.sprintf "passed to `%s`" (Procname.to_simplified_string pname))
var var
in in
@ -342,9 +343,10 @@ module TransferFunctions = struct
report_on_non_nullable_arg ?annotations domain args report_on_non_nullable_arg ?annotations domain args
let exec_instr (astate : Domain.t) {ProcData.summary} _cfg_node (instr : Sil.instr) = let exec_instr (astate : Domain.t) {IntraproceduralAnalysis.proc_desc; err_log} _cfg_node
let attributes = Summary.get_attributes summary in (instr : Sil.instr) =
let astate = report_unchecked_strongself_issues_on_exps astate summary instr in let attributes = Procdesc.get_attributes proc_desc in
let astate = report_unchecked_strongself_issues_on_exps attributes err_log astate instr in
let astate = remove_ids_in_closures_from_domain astate instr in let astate = remove_ids_in_closures_from_domain astate instr in
match instr with match instr with
| Load {id; e= Lvar pvar; loc; typ} -> | Load {id; e= Lvar pvar; loc; typ} ->
@ -385,8 +387,7 @@ module TransferFunctions = struct
| Prune (UnOp (LNot, BinOp (Binop.Eq, Var id, e), _), _, _, _) -> | Prune (UnOp (LNot, BinOp (Binop.Eq, Var id, e), _), _, _, _) ->
if Exp.is_null_literal e then exec_null_check_id astate id else astate if Exp.is_null_literal e then exec_null_check_id astate id else astate
| Call (_, Exp.Const (Const.Cfun callee_pn), args, _, _) -> | Call (_, Exp.Const (Const.Cfun callee_pn), args, _, _) ->
let astate = report_unchecked_strongself_issues_on_args astate summary callee_pn args in report_unchecked_strongself_issues_on_args attributes err_log astate callee_pn args
astate
| _ -> | _ ->
astate astate
end end
@ -425,7 +426,8 @@ let make_trace_captured_strong_self domain =
Location.compare loc1 loc2 ) Location.compare loc1 loc2 )
let report_mix_self_weakself_issues summary domain (weakSelf : DomainData.t) (self : DomainData.t) = let report_mix_self_weakself_issues attributes err_log domain (weakSelf : DomainData.t)
(self : DomainData.t) =
let message = let message =
F.asprintf F.asprintf
"This block uses both `%a` (%a) and `%a` (%a). This could lead to retain cycles or \ "This block uses both `%a` (%a) and `%a` (%a). This could lead to retain cycles or \
@ -434,11 +436,11 @@ let report_mix_self_weakself_issues summary domain (weakSelf : DomainData.t) (se
Location.pp self.loc Location.pp self.loc
in in
let ltr = make_trace_use_self_weakself domain in let ltr = make_trace_use_self_weakself domain in
SummaryReporting.log_error summary ~ltr ~loc:self.loc IssueType.mixed_self_weakself message Reporting.log_error attributes err_log ~ltr ~loc:self.loc IssueType.mixed_self_weakself message
let report_weakself_in_no_escape_block_issues summary domain (weakSelf : DomainData.t) procname let report_weakself_in_no_escape_block_issues attributes err_log domain (weakSelf : DomainData.t)
reported_weak_self_in_noescape_block = procname reported_weak_self_in_noescape_block =
if not (Pvar.Set.mem weakSelf.pvar reported_weak_self_in_noescape_block) then ( if not (Pvar.Set.mem weakSelf.pvar reported_weak_self_in_noescape_block) then (
let reported_weak_self_in_noescape_block = let reported_weak_self_in_noescape_block =
Pvar.Set.add weakSelf.pvar reported_weak_self_in_noescape_block Pvar.Set.add weakSelf.pvar reported_weak_self_in_noescape_block
@ -451,13 +453,13 @@ let report_weakself_in_no_escape_block_issues summary domain (weakSelf : DomainD
(Procname.to_simplified_string procname) (Procname.to_simplified_string procname)
in in
let ltr = make_trace_use_self_weakself domain in let ltr = make_trace_use_self_weakself domain in
SummaryReporting.log_error summary ~ltr ~loc:weakSelf.loc IssueType.weak_self_in_noescape_block Reporting.log_error attributes err_log ~ltr ~loc:weakSelf.loc
message ; IssueType.weak_self_in_noescape_block message ;
reported_weak_self_in_noescape_block ) reported_weak_self_in_noescape_block )
else reported_weak_self_in_noescape_block else reported_weak_self_in_noescape_block
let report_weakself_multiple_issue summary domain (weakSelf1 : DomainData.t) let report_weakself_multiple_issue attributes err_log domain (weakSelf1 : DomainData.t)
(weakSelf2 : DomainData.t) = (weakSelf2 : DomainData.t) =
let message = let message =
F.asprintf F.asprintf
@ -469,10 +471,10 @@ let report_weakself_multiple_issue summary domain (weakSelf1 : DomainData.t)
(Pvar.pp Pp.text) weakSelf1.pvar (Pvar.pp Pp.text) weakSelf1.pvar (Pvar.pp Pp.text) weakSelf1.pvar (Pvar.pp Pp.text) weakSelf1.pvar
in in
let ltr = make_trace_use_self_weakself domain in let ltr = make_trace_use_self_weakself domain in
SummaryReporting.log_error summary ~ltr ~loc:weakSelf1.loc IssueType.multiple_weakself message Reporting.log_error attributes err_log ~ltr ~loc:weakSelf1.loc IssueType.multiple_weakself message
let report_captured_strongself_issue domain summary attributes (capturedStrongSelf : DomainData.t) let report_captured_strongself_issue attributes err_log domain (capturedStrongSelf : DomainData.t)
report_captured_strongself = report_captured_strongself =
if if
Option.is_none attributes.ProcAttributes.passed_as_noescape_block_to Option.is_none attributes.ProcAttributes.passed_as_noescape_block_to
@ -489,18 +491,18 @@ let report_captured_strongself_issue domain summary attributes (capturedStrongSe
(Pvar.pp Pp.text) capturedStrongSelf.pvar Location.pp capturedStrongSelf.loc (Pvar.pp Pp.text) capturedStrongSelf.pvar Location.pp capturedStrongSelf.loc
in in
let ltr = make_trace_captured_strong_self domain in let ltr = make_trace_captured_strong_self domain in
SummaryReporting.log_error summary ~ltr ~loc:capturedStrongSelf.loc Reporting.log_error attributes err_log ~ltr ~loc:capturedStrongSelf.loc
IssueType.captured_strong_self message ; IssueType.captured_strong_self message ;
report_captured_strongself ) report_captured_strongself )
else report_captured_strongself else report_captured_strongself
let report_issues summary domain attributes = let report_issues attributes err_log domain =
let process_domain_item (result : report_issues_result) (_, (domain_data : DomainData.t)) = let process_domain_item (result : report_issues_result) (_, (domain_data : DomainData.t)) =
match domain_data.kind with match domain_data.kind with
| DomainData.CAPTURED_STRONG_SELF -> | DomainData.CAPTURED_STRONG_SELF ->
let reported_captured_strong_self = let reported_captured_strong_self =
report_captured_strongself_issue domain summary attributes domain_data report_captured_strongself_issue attributes err_log domain domain_data
result.reported_captured_strong_self result.reported_captured_strong_self
in in
{result with reported_captured_strong_self} {result with reported_captured_strong_self}
@ -508,8 +510,8 @@ let report_issues summary domain attributes =
let reported_weak_self_in_noescape_block = let reported_weak_self_in_noescape_block =
match attributes.ProcAttributes.passed_as_noescape_block_to with match attributes.ProcAttributes.passed_as_noescape_block_to with
| Some procname -> | Some procname ->
report_weakself_in_no_escape_block_issues summary domain domain_data procname report_weakself_in_no_escape_block_issues attributes err_log domain domain_data
result.reported_weak_self_in_noescape_block procname result.reported_weak_self_in_noescape_block
| None -> | None ->
result.reported_weak_self_in_noescape_block result.reported_weak_self_in_noescape_block
in in
@ -539,28 +541,25 @@ let report_issues summary domain attributes =
let selfList = List.rev selfList in let selfList = List.rev selfList in
( match (weakSelfList, selfList) with ( match (weakSelfList, selfList) with
| weakSelf :: _, self :: _ -> | weakSelf :: _, self :: _ ->
report_mix_self_weakself_issues summary domain weakSelf self report_mix_self_weakself_issues attributes err_log domain weakSelf self
| _ -> | _ ->
() ) ; () ) ;
match weakSelfList with match weakSelfList with
| weakSelf1 :: weakSelf2 :: _ -> | weakSelf1 :: weakSelf2 :: _ ->
report_weakself_multiple_issue summary domain weakSelf1 weakSelf2 report_weakself_multiple_issue attributes err_log domain weakSelf1 weakSelf2
| _ -> | _ ->
() ()
module Analyzer = AbstractInterpreter.MakeWTO (TransferFunctions) module Analyzer = AbstractInterpreter.MakeWTO (TransferFunctions)
let checker {Callbacks.exe_env; summary} = let checker ({IntraproceduralAnalysis.proc_desc; err_log} as analysis_data) =
let initial = {Domain.vars= Vars.empty; strongVars= StrongEqualToWeakCapturedVars.empty} in let initial = {Domain.vars= Vars.empty; strongVars= StrongEqualToWeakCapturedVars.empty} in
let procname = Summary.get_proc_name summary in let procname = Procdesc.get_proc_name proc_desc in
let tenv = Exe_env.get_tenv exe_env procname in if Procname.is_objc_block procname then
let proc_data = {ProcData.summary; tenv; extras= ()} in match Analyzer.compute_post analysis_data ~initial proc_desc with
let attributes = Summary.get_attributes summary in
( if Procname.is_objc_block procname then
match Analyzer.compute_post proc_data ~initial (Summary.get_proc_desc summary) with
| Some domain -> | Some domain ->
report_issues summary domain.vars attributes let attributes = Procdesc.get_attributes proc_desc in
report_issues attributes err_log domain.vars
| None -> | None ->
() ) ; ()
summary

@ -7,4 +7,4 @@
open! IStd open! IStd
val checker : Callbacks.proc_callback_t val checker : IntraproceduralAnalysis.t -> unit

Loading…
Cancel
Save