diff --git a/infer/src/checkers/annotations.ml b/infer/src/checkers/annotations.ml index 3fcb006e8..7d4c73a4f 100644 --- a/infer/src/checkers/annotations.ml +++ b/infer/src/checkers/annotations.ml @@ -13,6 +13,8 @@ open! IStd let any_thread = "AnyThread" +let auto_cleanup = "AutoCleanup" + let bind = "Bind" let bind_view = "BindView" diff --git a/infer/src/checkers/annotations.mli b/infer/src/checkers/annotations.mli index a9848f0d9..45f93f0dc 100644 --- a/infer/src/checkers/annotations.mli +++ b/infer/src/checkers/annotations.mli @@ -13,6 +13,8 @@ open! IStd val any_thread : string +val auto_cleanup : string + val expensive : string val inject_prop : string diff --git a/infer/src/checkers/fragmentRetainsViewChecker.ml b/infer/src/checkers/fragmentRetainsViewChecker.ml index 1bc24156b..0bd41cbc3 100644 --- a/infer/src/checkers/fragmentRetainsViewChecker.ml +++ b/infer/src/checkers/fragmentRetainsViewChecker.ml @@ -45,9 +45,12 @@ let callback_fragment_retains_view_java pname_java {Callbacks.proc_desc; summary let fields_nullified = PatternMatch.get_fields_nullified proc_desc in (* report if a field is declared by C, but not nulled out in C.onDestroyView *) List.iter - ~f:(fun (fname, fld_typ, _) -> - if not (Typ.Fieldname.Set.mem fname fields_nullified) then - report_error (Typ.mk (Tstruct class_typename)) fname fld_typ summary proc_desc ) + ~f:(fun (fname, fld_typ, ia) -> + if + not + ( Annotations.ia_ends_with ia Annotations.auto_cleanup + || Typ.Fieldname.Set.mem fname fields_nullified ) + then report_error (Typ.mk (Tstruct class_typename)) fname fld_typ summary proc_desc ) declared_view_fields | _ -> () diff --git a/infer/tests/codetoanalyze/java/checkers/AutoCleanup.java b/infer/tests/codetoanalyze/java/checkers/AutoCleanup.java new file mode 100644 index 000000000..1a9c11346 --- /dev/null +++ b/infer/tests/codetoanalyze/java/checkers/AutoCleanup.java @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2018 - 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. + */ +package codetoanalyze.java.checkers; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +@Target(value = ElementType.FIELD) +public @interface AutoCleanup {} diff --git a/infer/tests/codetoanalyze/java/checkers/FragmentDoesNotRetainViewExample.java b/infer/tests/codetoanalyze/java/checkers/FragmentDoesNotRetainViewExample.java index c1d014fdb..5e6a24d1c 100644 --- a/infer/tests/codetoanalyze/java/checkers/FragmentDoesNotRetainViewExample.java +++ b/infer/tests/codetoanalyze/java/checkers/FragmentDoesNotRetainViewExample.java @@ -32,6 +32,7 @@ public class FragmentDoesNotRetainViewExample extends Fragment { View mView2; ViewGroup mViewSubclass; CustomView mCustomView; + @AutoCleanup View mWillBeCleanedUp; boolean b; @@ -41,6 +42,7 @@ public class FragmentDoesNotRetainViewExample extends Fragment { mView2 = inflater.inflate(-1, container, false); mViewSubclass = (ViewGroup) inflater.inflate(-1, container, false); mCustomView = (CustomView) inflater.inflate(-1, container, false); + mWillBeCleanedUp = inflater.inflate(-1, container, false); return container; }