Reviewed By: cristianoc Differential Revision: D3187908 fb-gh-sync-id: ae78e9e fbshipit-source-id: ae78e9emaster
parent
66d3d492f8
commit
6113497020
@ -1,115 +0,0 @@
|
|||||||
(*
|
|
||||||
* Copyright (c) 2013 - present Facebook, Inc.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the BSD style license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*)
|
|
||||||
|
|
||||||
open! Utils
|
|
||||||
|
|
||||||
(** Make sure callbacks are always unregistered. drive the point home by reporting possible NPE's *)
|
|
||||||
|
|
||||||
module L = Logging
|
|
||||||
module F = Format
|
|
||||||
module P = Printf
|
|
||||||
module IdSet = Ident.IdentSet
|
|
||||||
module FldSet = Ident.FieldSet
|
|
||||||
|
|
||||||
(** set of instance fields belonging to the current file that are assigned to null literals *)
|
|
||||||
let fields_nullified = ref FldSet.empty
|
|
||||||
|
|
||||||
(** set of callbacks registered in the current file *)
|
|
||||||
let registered_callback_procs = ref Procname.Set.empty
|
|
||||||
|
|
||||||
let android_lifecycle_typs = ref []
|
|
||||||
|
|
||||||
(** resolve the list of android lifecycle type strings in [tenv] *)
|
|
||||||
let get_or_create_lifecycle_typs tenv = match !android_lifecycle_typs with
|
|
||||||
| [] ->
|
|
||||||
let lifecycle_typs = IList.fold_left (fun typs (pkg, clazz, methods) ->
|
|
||||||
let qualified_name = Mangled.from_package_class pkg clazz in
|
|
||||||
match AndroidFramework.get_lifecycle_for_framework_typ_opt
|
|
||||||
qualified_name methods tenv with
|
|
||||||
| Some (framework_typ, _) -> framework_typ :: typs
|
|
||||||
| None -> typs
|
|
||||||
) [] AndroidFramework.get_lifecycles in
|
|
||||||
android_lifecycle_typs := lifecycle_typs;
|
|
||||||
lifecycle_typs
|
|
||||||
| typs -> typs
|
|
||||||
|
|
||||||
|
|
||||||
let num_methods_checked = ref 0
|
|
||||||
|
|
||||||
let done_checking num_methods =
|
|
||||||
incr num_methods_checked;
|
|
||||||
!num_methods_checked = num_methods
|
|
||||||
|
|
||||||
(** ask Eradicate to check each of the procs in [registered_callback_procs] (and their transitive
|
|
||||||
* callees) in a context where each of the fields in [fields_nullifed] is marked as @Nullable *)
|
|
||||||
let do_eradicate_check ({ Callbacks.get_proc_desc } as callback_args) =
|
|
||||||
(* tell Eradicate to treat each of the fields nullified in on_destroy as nullable *)
|
|
||||||
FldSet.iter (fun fld -> Models.Inference.field_add_nullable_annotation fld) !fields_nullified;
|
|
||||||
Procname.Set.iter
|
|
||||||
(fun proc_name ->
|
|
||||||
match get_proc_desc proc_name with
|
|
||||||
| Some proc_desc ->
|
|
||||||
Eradicate.callback_eradicate
|
|
||||||
{ callback_args with Callbacks.proc_name; proc_desc }
|
|
||||||
| None -> ())
|
|
||||||
!registered_callback_procs
|
|
||||||
|
|
||||||
(** if [procname] belongs to an Android lifecycle type, save the set of callbacks registered in
|
|
||||||
* [procname]. in addition, if [procname] is a special "destroy" /"cleanup" method, save the set of
|
|
||||||
* fields that are nullified *)
|
|
||||||
let callback_checker_main_java
|
|
||||||
proc_name_java ({ Callbacks.proc_desc; tenv } as callback_args) =
|
|
||||||
let typename =
|
|
||||||
Typename.TN_csu
|
|
||||||
(Csu.Class Csu.Java,
|
|
||||||
Mangled.from_string (Procname.java_get_class_name proc_name_java)) in
|
|
||||||
match Tenv.lookup tenv typename with
|
|
||||||
| Some ({ struct_name = Some _; def_methods } as struct_typ) ->
|
|
||||||
let typ = Sil.Tstruct struct_typ in
|
|
||||||
let lifecycle_typs = get_or_create_lifecycle_typs tenv in
|
|
||||||
let proc_belongs_to_lifecycle_typ = IList.exists
|
|
||||||
(fun lifecycle_typ -> AndroidFramework.typ_is_lifecycle_typ typ lifecycle_typ tenv)
|
|
||||||
lifecycle_typs in
|
|
||||||
if proc_belongs_to_lifecycle_typ then
|
|
||||||
(* TODO (tt4959422): get all of the callbacks registered by callees as well *)
|
|
||||||
let registered_callback_typs =
|
|
||||||
AndroidFramework.get_callbacks_registered_by_proc proc_desc tenv in
|
|
||||||
(* find the callbacks registered by this procedure and update the list *)
|
|
||||||
let registered_callback_procs' = IList.fold_left
|
|
||||||
(fun callback_procs callback_typ ->
|
|
||||||
match callback_typ with
|
|
||||||
| Sil.Tptr (Sil.Tstruct
|
|
||||||
{ Sil.struct_name = Some _; def_methods = def_methods'}, _) ->
|
|
||||||
IList.fold_left
|
|
||||||
(fun callback_procs callback_proc ->
|
|
||||||
if Procname.is_constructor callback_proc then callback_procs
|
|
||||||
else Procname.Set.add callback_proc callback_procs)
|
|
||||||
callback_procs
|
|
||||||
def_methods'
|
|
||||||
| _ -> callback_procs)
|
|
||||||
!registered_callback_procs
|
|
||||||
registered_callback_typs in
|
|
||||||
registered_callback_procs := registered_callback_procs';
|
|
||||||
let _ = if AndroidFramework.is_destroy_method callback_args.Callbacks.proc_name then
|
|
||||||
(* compute the set of fields nullified by this procedure *)
|
|
||||||
(* TODO (t4959422): get fields that are nullified in callees of the destroy method *)
|
|
||||||
fields_nullified :=
|
|
||||||
FldSet.union (PatternMatch.get_fields_nullified proc_desc) !fields_nullified in
|
|
||||||
if done_checking (IList.length def_methods) then
|
|
||||||
do_eradicate_check callback_args
|
|
||||||
| _ -> ()
|
|
||||||
|
|
||||||
|
|
||||||
let callback_checker_main
|
|
||||||
({ Callbacks.proc_name } as callback_args) =
|
|
||||||
match proc_name with
|
|
||||||
| Procname.Java pname_java ->
|
|
||||||
callback_checker_main_java pname_java callback_args
|
|
||||||
| _ ->
|
|
||||||
()
|
|
@ -1,14 +0,0 @@
|
|||||||
(*
|
|
||||||
* Copyright (c) 2013 - present Facebook, Inc.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the BSD style license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*)
|
|
||||||
|
|
||||||
open! Utils
|
|
||||||
|
|
||||||
(** Make sure callbacks are always unregistered. drive the point home by reporting possible NPE's *)
|
|
||||||
|
|
||||||
val callback_checker_main : Callbacks.proc_callback_t
|
|
Loading…
Reference in new issue