From 07da8f36d175d12d84bebbb32bac7f6c764f2f9f Mon Sep 17 00:00:00 2001 From: Peter O'Hearn Date: Thu, 13 Oct 2016 09:42:17 -0700 Subject: [PATCH] don't warn on GuardedBy self reference Reviewed By: sblackshear Differential Revision: D4015092 fbshipit-source-id: 7a82710 --- infer/src/backend/rearrange.ml | 6 +++- .../java/infer/GuardedByExample.java | 32 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/infer/src/backend/rearrange.ml b/infer/src/backend/rearrange.ml index 704324a46..572c1315f 100644 --- a/infer/src/backend/rearrange.ml +++ b/infer/src/backend/rearrange.ml @@ -744,6 +744,9 @@ let add_guarded_by_constraints tenv prop lexp pdesc = | Sil.Apred (Alocked, _) -> true | _ -> false) (Attribute.get_for_exp tenv prop guarded_by_exp) in + let guardedby_is_self_referential = + string_equal "itself" (String.lowercase guarded_by_str) || + string_is_suffix guarded_by_str (Ident.fieldname_to_string accessed_fld) in let should_warn pdesc = (* adding this check implements "by reference" semantics for guarded-by rather than "by value" semantics. if this access is through a local L or field V.f @@ -767,7 +770,8 @@ let add_guarded_by_constraints tenv prop lexp pdesc = Cfg.Procdesc.get_access pdesc <> PredSymb.Private && not (Annotations.pdesc_has_annot pdesc Annotations.visibleForTesting) && not (Procname.java_is_access_method (Cfg.Procdesc.get_proc_name pdesc)) && - not (is_accessible_through_local_ref lexp) in + not (is_accessible_through_local_ref lexp) && + not guardedby_is_self_referential in match find_guarded_by_exp guarded_by_str prop.Prop.sigma with | Some (Sil.Eexp (guarded_by_exp, _), typ) -> if is_read_write_lock typ diff --git a/infer/tests/codetoanalyze/java/infer/GuardedByExample.java b/infer/tests/codetoanalyze/java/infer/GuardedByExample.java index 920a7e902..8f92eed68 100644 --- a/infer/tests/codetoanalyze/java/infer/GuardedByExample.java +++ b/infer/tests/codetoanalyze/java/infer/GuardedByExample.java @@ -370,4 +370,36 @@ public class GuardedByExample { } } + @GuardedBy("self_reference") + Object self_reference; + + void guardedBySelfReferenceOK() { + synchronized(self_reference){ + this.self_reference.toString(); + } + } + + // TODO: report on this case, or at least a version which writes + /* + void guardedBySelfReferenceBad() { + this.self_reference.toString(); + } + */ + + @GuardedBy("itself") + Object itself_fld; + + void itselfOK() { + synchronized(itself_fld){ + this.itself_fld.toString(); + } + } + + // TODO: report on this case, or at least a version which writes + /* + void itselfBad() { + this.itself_fld.toString(); + } + */ + }