diff --git a/infer/src/checkers/annotations.ml b/infer/src/checkers/annotations.ml index 620914396..05677876d 100644 --- a/infer/src/checkers/annotations.ml +++ b/infer/src/checkers/annotations.ml @@ -47,6 +47,8 @@ let initializer_ = "Initializer" let inject = "Inject" +let inject_prop = "InjectProp" + let inject_view = "InjectView" let mutable_ = "Mutable" diff --git a/infer/src/checkers/annotations.mli b/infer/src/checkers/annotations.mli index 5bca4fb7e..a9848f0d9 100644 --- a/infer/src/checkers/annotations.mli +++ b/infer/src/checkers/annotations.mli @@ -15,6 +15,8 @@ val any_thread : string val expensive : string +val inject_prop : string + val no_allocation : string val nullable : string diff --git a/infer/src/concurrency/RacerD.ml b/infer/src/concurrency/RacerD.ml index 7b01cd44e..03290d64b 100644 --- a/infer/src/concurrency/RacerD.ml +++ b/infer/src/concurrency/RacerD.ml @@ -730,6 +730,7 @@ let empty_post : RacerDDomain.summary = let analyze_procedure {Callbacks.proc_desc; get_proc_desc; tenv; summary} = let open RacerDConfig in + let method_annotation = (Procdesc.get_attributes proc_desc).method_annotation in let is_initializer tenv proc_name = Typ.Procname.is_constructor proc_name || FbThreadSafety.is_custom_init tenv proc_name in @@ -761,8 +762,17 @@ let analyze_procedure {Callbacks.proc_desc; get_proc_desc; tenv; summary} = | _ -> OwnershipDomain.empty in + let is_owned_formal {Annot.class_name} = + (* @InjectProp allocates a fresh object to bind to the parameter *) + String.is_suffix ~suffix:Annotations.inject_prop class_name + in let add_conditional_owned_formal acc (formal, formal_index) = - OwnershipDomain.add (formal, []) (OwnershipAbstractValue.make_owned_if formal_index) acc + let ownership_value = + if Annotations.ma_has_annotation_with method_annotation is_owned_formal then + OwnershipAbstractValue.owned + else OwnershipAbstractValue.make_owned_if formal_index + in + OwnershipDomain.add (formal, []) ownership_value acc in if is_initializer tenv (Procdesc.get_proc_name proc_desc) then let add_owned_formal acc formal_index = diff --git a/infer/tests/codetoanalyze/java/racerd/Annotations.java b/infer/tests/codetoanalyze/java/racerd/Annotations.java index b907fe7b3..a937864d5 100644 --- a/infer/tests/codetoanalyze/java/racerd/Annotations.java +++ b/infer/tests/codetoanalyze/java/racerd/Annotations.java @@ -62,6 +62,11 @@ import com.facebook.infer.annotation.ThreadSafe; @interface MyThreadSafeAlias2 { } +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.CLASS) +@interface InjectProp { +} + interface Interface { @Functional Object functionalMethod(); @@ -398,4 +403,8 @@ class Annotations implements Interface { a.mSynchronizedMap.put(new Object(), new Object()); } + public void injectPropOk(@InjectProp Obj o) { + o.f = 7; + } + }