|
|
@ -229,7 +229,7 @@ module TransferFunctions = struct
|
|
|
|
Location.compare loc1 loc2 )
|
|
|
|
Location.compare loc1 loc2 )
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let report_unchecked_strongself_issues attributes err_log (domain : Domain.t) var_use var =
|
|
|
|
let report_unchecked_strongself_issues proc_desc 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
|
|
|
|
Reporting.log_error attributes err_log ~ltr ~loc IssueType.strong_self_not_checked message ;
|
|
|
|
Reporting.log_error proc_desc 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,12 +251,12 @@ module TransferFunctions = struct
|
|
|
|
domain
|
|
|
|
domain
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let report_unchecked_strongself_issues_on_exps attributes err_log (domain : Domain.t)
|
|
|
|
let report_unchecked_strongself_issues_on_exps proc_desc err_log (domain : Domain.t)
|
|
|
|
(instr : Sil.instr) =
|
|
|
|
(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 attributes err_log domain "dereferenced" var
|
|
|
|
report_unchecked_strongself_issues proc_desc err_log domain "dereferenced" var
|
|
|
|
| _ ->
|
|
|
|
| _ ->
|
|
|
|
strongVars
|
|
|
|
strongVars
|
|
|
|
in
|
|
|
|
in
|
|
|
@ -306,9 +306,9 @@ module TransferFunctions = struct
|
|
|
|
None
|
|
|
|
None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let report_unchecked_strongself_issues_on_args attributes err_log (domain : Domain.t) pname args =
|
|
|
|
let report_unchecked_strongself_issues_on_args proc_desc err_log (domain : Domain.t) pname args =
|
|
|
|
let report_issue var =
|
|
|
|
let report_issue var =
|
|
|
|
report_unchecked_strongself_issues attributes err_log domain
|
|
|
|
report_unchecked_strongself_issues proc_desc 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
|
|
|
@ -346,7 +346,7 @@ module TransferFunctions = struct
|
|
|
|
let exec_instr (astate : Domain.t) {IntraproceduralAnalysis.proc_desc; err_log} _cfg_node
|
|
|
|
let exec_instr (astate : Domain.t) {IntraproceduralAnalysis.proc_desc; err_log} _cfg_node
|
|
|
|
(instr : Sil.instr) =
|
|
|
|
(instr : Sil.instr) =
|
|
|
|
let attributes = Procdesc.get_attributes proc_desc 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 = report_unchecked_strongself_issues_on_exps proc_desc 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} ->
|
|
|
@ -387,7 +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, _, _) ->
|
|
|
|
report_unchecked_strongself_issues_on_args attributes err_log astate callee_pn args
|
|
|
|
report_unchecked_strongself_issues_on_args proc_desc err_log astate callee_pn args
|
|
|
|
| _ ->
|
|
|
|
| _ ->
|
|
|
|
astate
|
|
|
|
astate
|
|
|
|
end
|
|
|
|
end
|
|
|
@ -426,7 +426,7 @@ let make_trace_captured_strong_self domain =
|
|
|
|
Location.compare loc1 loc2 )
|
|
|
|
Location.compare loc1 loc2 )
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let report_mix_self_weakself_issues attributes err_log domain (weakSelf : DomainData.t)
|
|
|
|
let report_mix_self_weakself_issues proc_desc err_log domain (weakSelf : DomainData.t)
|
|
|
|
(self : DomainData.t) =
|
|
|
|
(self : DomainData.t) =
|
|
|
|
let message =
|
|
|
|
let message =
|
|
|
|
F.asprintf
|
|
|
|
F.asprintf
|
|
|
@ -436,10 +436,10 @@ let report_mix_self_weakself_issues attributes err_log domain (weakSelf : Domain
|
|
|
|
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
|
|
|
|
Reporting.log_error attributes err_log ~ltr ~loc:self.loc IssueType.mixed_self_weakself message
|
|
|
|
Reporting.log_error proc_desc err_log ~ltr ~loc:self.loc IssueType.mixed_self_weakself message
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let report_weakself_in_no_escape_block_issues attributes err_log domain (weakSelf : DomainData.t)
|
|
|
|
let report_weakself_in_no_escape_block_issues proc_desc err_log domain (weakSelf : DomainData.t)
|
|
|
|
procname 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 =
|
|
|
@ -453,13 +453,13 @@ let report_weakself_in_no_escape_block_issues attributes err_log domain (weakSel
|
|
|
|
(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
|
|
|
|
Reporting.log_error attributes err_log ~ltr ~loc:weakSelf.loc
|
|
|
|
Reporting.log_error proc_desc err_log ~ltr ~loc:weakSelf.loc
|
|
|
|
IssueType.weak_self_in_noescape_block 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 attributes err_log domain (weakSelf1 : DomainData.t)
|
|
|
|
let report_weakself_multiple_issue proc_desc err_log domain (weakSelf1 : DomainData.t)
|
|
|
|
(weakSelf2 : DomainData.t) =
|
|
|
|
(weakSelf2 : DomainData.t) =
|
|
|
|
let message =
|
|
|
|
let message =
|
|
|
|
F.asprintf
|
|
|
|
F.asprintf
|
|
|
@ -471,11 +471,12 @@ let report_weakself_multiple_issue attributes err_log domain (weakSelf1 : Domain
|
|
|
|
(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
|
|
|
|
Reporting.log_error attributes err_log ~ltr ~loc:weakSelf1.loc IssueType.multiple_weakself message
|
|
|
|
Reporting.log_error proc_desc err_log ~ltr ~loc:weakSelf1.loc IssueType.multiple_weakself message
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let report_captured_strongself_issue attributes err_log domain (capturedStrongSelf : DomainData.t)
|
|
|
|
let report_captured_strongself_issue proc_desc err_log domain (capturedStrongSelf : DomainData.t)
|
|
|
|
report_captured_strongself =
|
|
|
|
report_captured_strongself =
|
|
|
|
|
|
|
|
let attributes = Procdesc.get_attributes proc_desc in
|
|
|
|
if
|
|
|
|
if
|
|
|
|
Option.is_none attributes.ProcAttributes.passed_as_noescape_block_to
|
|
|
|
Option.is_none attributes.ProcAttributes.passed_as_noescape_block_to
|
|
|
|
&& not (Pvar.Set.mem capturedStrongSelf.pvar report_captured_strongself)
|
|
|
|
&& not (Pvar.Set.mem capturedStrongSelf.pvar report_captured_strongself)
|
|
|
@ -491,26 +492,27 @@ let report_captured_strongself_issue attributes err_log domain (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
|
|
|
|
Reporting.log_error attributes err_log ~ltr ~loc:capturedStrongSelf.loc
|
|
|
|
Reporting.log_error proc_desc 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 attributes err_log domain =
|
|
|
|
let report_issues proc_desc 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 attributes err_log domain domain_data
|
|
|
|
report_captured_strongself_issue proc_desc 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}
|
|
|
|
| DomainData.WEAK_SELF ->
|
|
|
|
| DomainData.WEAK_SELF ->
|
|
|
|
let reported_weak_self_in_noescape_block =
|
|
|
|
let reported_weak_self_in_noescape_block =
|
|
|
|
|
|
|
|
let attributes = Procdesc.get_attributes proc_desc in
|
|
|
|
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 attributes err_log domain domain_data
|
|
|
|
report_weakself_in_no_escape_block_issues proc_desc err_log domain domain_data
|
|
|
|
procname 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
|
|
|
@ -541,12 +543,12 @@ let report_issues attributes err_log domain =
|
|
|
|
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 attributes err_log domain weakSelf self
|
|
|
|
report_mix_self_weakself_issues proc_desc err_log domain weakSelf self
|
|
|
|
| _ ->
|
|
|
|
| _ ->
|
|
|
|
() ) ;
|
|
|
|
() ) ;
|
|
|
|
match weakSelfList with
|
|
|
|
match weakSelfList with
|
|
|
|
| weakSelf1 :: weakSelf2 :: _ ->
|
|
|
|
| weakSelf1 :: weakSelf2 :: _ ->
|
|
|
|
report_weakself_multiple_issue attributes err_log domain weakSelf1 weakSelf2
|
|
|
|
report_weakself_multiple_issue proc_desc err_log domain weakSelf1 weakSelf2
|
|
|
|
| _ ->
|
|
|
|
| _ ->
|
|
|
|
()
|
|
|
|
()
|
|
|
|
|
|
|
|
|
|
|
@ -559,7 +561,6 @@ let checker ({IntraproceduralAnalysis.proc_desc; err_log} as analysis_data) =
|
|
|
|
if Procname.is_objc_block procname then
|
|
|
|
if Procname.is_objc_block procname then
|
|
|
|
match Analyzer.compute_post analysis_data ~initial proc_desc with
|
|
|
|
match Analyzer.compute_post analysis_data ~initial proc_desc with
|
|
|
|
| Some domain ->
|
|
|
|
| Some domain ->
|
|
|
|
let attributes = Procdesc.get_attributes proc_desc in
|
|
|
|
report_issues proc_desc err_log domain.vars
|
|
|
|
report_issues attributes err_log domain.vars
|
|
|
|
|
|
|
|
| None ->
|
|
|
|
| None ->
|
|
|
|
()
|
|
|
|
()
|
|
|
|