From 70df06a596f9f844fd1e28d18da788ac0ddb5bb4 Mon Sep 17 00:00:00 2001 From: Sam Blackshear Date: Mon, 30 Jan 2017 11:32:47 -0800 Subject: [PATCH] [thread-safety] don't consider VisibleForTesting methods as public Summary: We warn on unsafe accesses to fields that occur in a public method (or are reachable from a public method). We ought not to consider VisibleForTesting methods as public, since they are only public for testing purposes. Reviewed By: peterogithub Differential Revision: D4477648 fbshipit-source-id: 5f58914 --- infer/src/checkers/ThreadSafety.ml | 3 ++- .../java/threadsafety/ThreadSafeExample.java | 13 +++++++++++++ .../codetoanalyze/java/threadsafety/issues.exp | 1 + 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/infer/src/checkers/ThreadSafety.ml b/infer/src/checkers/ThreadSafety.ml index 0e5254db7..5ecccf0c3 100644 --- a/infer/src/checkers/ThreadSafety.ml +++ b/infer/src/checkers/ThreadSafety.ml @@ -455,7 +455,8 @@ let should_analyze_proc pdesc tenv = (* return true if we should report on unprotected accesses during the procedure *) let should_report_on_proc (_, _, proc_name, proc_desc) = not (Procname.java_is_autogen_method proc_name) && - Procdesc.get_access proc_desc <> PredSymb.Private + Procdesc.get_access proc_desc <> PredSymb.Private && + not (Annotations.pdesc_return_annot_ends_with proc_desc Annotations.visibleForTesting) (* creates a map from proc_envs to postconditions *) let make_results_table get_proc_desc file_env = diff --git a/infer/tests/codetoanalyze/java/threadsafety/ThreadSafeExample.java b/infer/tests/codetoanalyze/java/threadsafety/ThreadSafeExample.java index 10886f137..f0b83f604 100644 --- a/infer/tests/codetoanalyze/java/threadsafety/ThreadSafeExample.java +++ b/infer/tests/codetoanalyze/java/threadsafety/ThreadSafeExample.java @@ -12,6 +12,8 @@ package codetoanalyze.java.checkers; import javax.annotation.concurrent.NotThreadSafe; import javax.annotation.concurrent.ThreadSafe; +import com.google.common.annotations.VisibleForTesting; + import com.facebook.infer.annotation.ThreadSafeMethod; @ThreadSafe @@ -101,6 +103,17 @@ public class ThreadSafeExample{ this.volatileField = new Object(); } + // don't count the method as public if it's marked VisibleForTesting + @VisibleForTesting + public void visibleForTestingNotPublicOk() { + this.f = 47; + } + + // but do complain if a VisibleForTesting method is called from a public method + public void callVisibleForTestingBad() { + visibleForTestingNotPublicOk(); + } + } class ExtendsThreadSafeExample extends ThreadSafeExample{ diff --git a/infer/tests/codetoanalyze/java/threadsafety/issues.exp b/infer/tests/codetoanalyze/java/threadsafety/issues.exp index 4a5f1da75..18ee7e878 100644 --- a/infer/tests/codetoanalyze/java/threadsafety/issues.exp +++ b/infer/tests/codetoanalyze/java/threadsafety/issues.exp @@ -35,6 +35,7 @@ codetoanalyze/java/threadsafety/ThreadSafeExample.java, void ExtendsThreadSafeEx codetoanalyze/java/threadsafety/ThreadSafeExample.java, void NonThreadSafeClass.threadSafeMethod(), 1, THREAD_SAFETY_VIOLATION, [access to codetoanalyze.java.checkers.NonThreadSafeClass.field] codetoanalyze/java/threadsafety/ThreadSafeExample.java, void NonThreadSafeSubclass.safeMethod(), 1, THREAD_SAFETY_VIOLATION, [access to codetoanalyze.java.checkers.NonThreadSafeClass.field] codetoanalyze/java/threadsafety/ThreadSafeExample.java, void ThreadSafeExample.callPublicMethodBad(), 1, THREAD_SAFETY_VIOLATION, [call to void ThreadSafeExample.assignInPrivateMethodOk(),access to codetoanalyze.java.checkers.ThreadSafeExample.f] +codetoanalyze/java/threadsafety/ThreadSafeExample.java, void ThreadSafeExample.callVisibleForTestingBad(), 1, THREAD_SAFETY_VIOLATION, [call to void ThreadSafeExample.visibleForTestingNotPublicOk(),access to codetoanalyze.java.checkers.ThreadSafeExample.f] codetoanalyze/java/threadsafety/ThreadSafeExample.java, void ThreadSafeExample.deeperTraceBad(), 1, THREAD_SAFETY_VIOLATION, [call to void ThreadSafeExample.callAssignInPrivateMethod(),call to void ThreadSafeExample.assignInPrivateMethodOk(),access to codetoanalyze.java.checkers.ThreadSafeExample.f] codetoanalyze/java/threadsafety/ThreadSafeExample.java, void ThreadSafeExample.oddBad(), 1, THREAD_SAFETY_VIOLATION, [call to void ThreadSafeExample.evenOk(),access to codetoanalyze.java.checkers.ThreadSafeExample.f] codetoanalyze/java/threadsafety/ThreadSafeExample.java, void ThreadSafeExample.recursiveBad(), 1, THREAD_SAFETY_VIOLATION, [access to codetoanalyze.java.checkers.ThreadSafeExample.f]