From 0105f280a31a4233f26e2e0bfabd959898158642 Mon Sep 17 00:00:00 2001 From: Nikos Gorogiannis Date: Wed, 2 Dec 2020 02:47:31 -0800 Subject: [PATCH] [racerd] consider ownership of interface calls Summary: The main point here is to ignore owned interfaces when considering whether to warn about non-thread-safe calls. Reviewed By: ezgicicek Differential Revision: D25187775 fbshipit-source-id: c2a7ce89c --- infer/src/concurrency/RacerDDomain.ml | 4 ++-- .../tests/codetoanalyze/java/racerd/Dispatch.java | 15 +++++++++++++++ infer/tests/codetoanalyze/java/racerd/issues.exp | 3 ++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/infer/src/concurrency/RacerDDomain.ml b/infer/src/concurrency/RacerDDomain.ml index 905b8a6e9..fe694443c 100644 --- a/infer/src/concurrency/RacerDDomain.ml +++ b/infer/src/concurrency/RacerDDomain.ml @@ -601,10 +601,10 @@ let pp fmt {threads; locks; accesses; ownership; attribute_map} = let add_unannotated_call_access formals pname actuals loc (astate : t) = apply_to_first_actual actuals astate ~f:(fun receiver -> + let ownership = OwnershipDomain.get_owned receiver astate.ownership in let access_opt = - (* FIXME this should use the ownership of the receiver! *) AccessSnapshot.make_unannotated_call_access formals receiver pname astate.locks - astate.threads Unowned loc + astate.threads ownership loc in {astate with accesses= AccessDomain.add_opt access_opt astate.accesses} ) diff --git a/infer/tests/codetoanalyze/java/racerd/Dispatch.java b/infer/tests/codetoanalyze/java/racerd/Dispatch.java index 24b045ef7..35c38390b 100644 --- a/infer/tests/codetoanalyze/java/racerd/Dispatch.java +++ b/infer/tests/codetoanalyze/java/racerd/Dispatch.java @@ -87,6 +87,21 @@ public class Dispatch { UnannotatedInterface owned = new UnannotadedImplementation(); privateCallUnnanotatedInterfaceOk(owned); } + + UnannotatedInterface mUnannotated; + + private void privateCallOk() { + mUnannotated.foo(); + } + + public void publicCallBad() { + privateCallOk(); + } + + public Dispatch() { + // this is OK even though public, since the object is owned + privateCallOk(); + } } class Some { diff --git a/infer/tests/codetoanalyze/java/racerd/issues.exp b/infer/tests/codetoanalyze/java/racerd/issues.exp index aefca4a27..3cc89b0e6 100644 --- a/infer/tests/codetoanalyze/java/racerd/issues.exp +++ b/infer/tests/codetoanalyze/java/racerd/issues.exp @@ -53,7 +53,8 @@ codetoanalyze/java/racerd/Containers.java, codetoanalyze.java.checkers.Container codetoanalyze/java/racerd/DeepOwnership.java, DeepOwnership.globalNotOwnedBad():void, 16, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [access to `DeepOwnership.global.next`] codetoanalyze/java/racerd/Dispatch.java, codetoanalyze.java.checkers.Dispatch.callUnannotatedInterfaceBad(codetoanalyze.java.checkers.UnannotatedInterface):void, 49, INTERFACE_NOT_THREAD_SAFE, no_bucket, WARNING, [Call to un-annotated interface method void UnannotatedInterface.foo()] codetoanalyze/java/racerd/Dispatch.java, codetoanalyze.java.checkers.Dispatch.callUnannotatedInterfaceIndirectBad(codetoanalyze.java.checkers.NotThreadSafe,codetoanalyze.java.checkers.UnannotatedInterface):void, 53, INTERFACE_NOT_THREAD_SAFE, no_bucket, WARNING, [call to void NotThreadSafe.notThreadSafeOk(UnannotatedInterface),Call to un-annotated interface method void UnannotatedInterface.foo()] -codetoanalyze/java/racerd/Dispatch.java, codetoanalyze.java.checkers.ThreadConfinedField.interfaceCallOnNormalFieldBad():void, 111, INTERFACE_NOT_THREAD_SAFE, no_bucket, WARNING, [Call to un-annotated interface method void UnannotatedInterface.foo()] +codetoanalyze/java/racerd/Dispatch.java, codetoanalyze.java.checkers.Dispatch.publicCallBad():void, 98, INTERFACE_NOT_THREAD_SAFE, no_bucket, WARNING, [call to void Dispatch.privateCallOk(),Call to un-annotated interface method void UnannotatedInterface.foo()] +codetoanalyze/java/racerd/Dispatch.java, codetoanalyze.java.checkers.ThreadConfinedField.interfaceCallOnNormalFieldBad():void, 126, INTERFACE_NOT_THREAD_SAFE, no_bucket, WARNING, [Call to un-annotated interface method void UnannotatedInterface.foo()] codetoanalyze/java/racerd/GuardedByTests.java, codetoanalyze.java.infer.GuardedByOther.accessBad():void, 127, GUARDEDBY_VIOLATION, no_bucket, WARNING, [access to `this.x`] codetoanalyze/java/racerd/GuardedByTests.java, codetoanalyze.java.infer.GuardedByTests.interprocUnlockedWriteBad():void, 59, GUARDEDBY_VIOLATION, no_bucket, WARNING, [call to void GuardedByTests.privateUnlockedWriteOk(),access to `this.d`] codetoanalyze/java/racerd/GuardedByTests.java, codetoanalyze.java.infer.GuardedByTests.unlockedWriteBad():void, 35, GUARDEDBY_VIOLATION, no_bucket, WARNING, [access to `this.b`]