From ff3159953de404915e944aeaaf3aba98773d0242 Mon Sep 17 00:00:00 2001 From: Sam Blackshear Date: Thu, 30 Mar 2017 12:04:51 -0700 Subject: [PATCH] [thread-safety] don't report read-write races when the write is in a private or autogenerated proc Reviewed By: jeremydubreil Differential Revision: D4800340 fbshipit-source-id: de4033e --- infer/src/checkers/ThreadSafety.ml | 8 +++++--- .../java/threadsafety/ThreadSafeExample.java | 10 ++++++++++ infer/tests/codetoanalyze/java/threadsafety/issues.exp | 1 - 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/infer/src/checkers/ThreadSafety.ml b/infer/src/checkers/ThreadSafety.ml index 1ce6dc049..90f3fa909 100644 --- a/infer/src/checkers/ThreadSafety.ml +++ b/infer/src/checkers/ThreadSafety.ml @@ -1056,7 +1056,7 @@ let report_unsafe_accesses ~should_report aggregated_access_map = { reported with reported_reads; reported_sites; } in let report_unsafe_access (access, pre, threaded, tenv, pdesc) accesses reported_acc = let pname = Procdesc.get_proc_name pdesc in - if is_duplicate_report access pname reported_acc || not (should_report pdesc tenv) + if is_duplicate_report access pname reported_acc then reported_acc else @@ -1128,9 +1128,11 @@ let report_unsafe_accesses ~should_report aggregated_access_map = let reported = { reported_acc with reported_writes = Typ.Procname.Set.empty; reported_reads = Typ.Procname.Set.empty; } in + let reportable_accesses = + List.filter ~f:(fun (_, _, _, tenv, pdesc) -> should_report pdesc tenv) grouped_accesses in List.fold - ~f:(fun acc access -> report_unsafe_access access grouped_accesses acc) - grouped_accesses + ~f:(fun acc access -> report_unsafe_access access reportable_accesses acc) + reportable_accesses ~init:reported) aggregated_access_map empty_reported diff --git a/infer/tests/codetoanalyze/java/threadsafety/ThreadSafeExample.java b/infer/tests/codetoanalyze/java/threadsafety/ThreadSafeExample.java index b0b0122db..b99b93db8 100644 --- a/infer/tests/codetoanalyze/java/threadsafety/ThreadSafeExample.java +++ b/infer/tests/codetoanalyze/java/threadsafety/ThreadSafeExample.java @@ -113,6 +113,16 @@ public class ThreadSafeExample{ visibleForTestingNotPublicOk(); } + Object sharedField; + + private void writePrivateSharedFieldOk() { + this.sharedField = new Object(); + } + + public Object returnSharedFieldOk() { + return this.sharedField; // ok because it only races with a private method + } + } class ExtendsThreadSafeExample extends ThreadSafeExample{ diff --git a/infer/tests/codetoanalyze/java/threadsafety/issues.exp b/infer/tests/codetoanalyze/java/threadsafety/issues.exp index 142266457..4ded6abbd 100644 --- a/infer/tests/codetoanalyze/java/threadsafety/issues.exp +++ b/infer/tests/codetoanalyze/java/threadsafety/issues.exp @@ -81,7 +81,6 @@ codetoanalyze/java/threadsafety/ThreadSafeExample.java, void ThreadSafeExample.o codetoanalyze/java/threadsafety/ThreadSafeExample.java, void ThreadSafeExample.recursiveBad(), 1, THREAD_SAFETY_VIOLATION, [access to codetoanalyze.java.checkers.ThreadSafeExample.f] codetoanalyze/java/threadsafety/ThreadSafeExample.java, void ThreadSafeExample.tsBad(), 1, THREAD_SAFETY_VIOLATION, [access to codetoanalyze.java.checkers.ThreadSafeExample.f] codetoanalyze/java/threadsafety/ThreadSafeExample.java, void YesThreadSafeExtendsNotThreadSafeExample.subsubmethodBad(), 1, THREAD_SAFETY_VIOLATION, [access to codetoanalyze.java.checkers.YesThreadSafeExtendsNotThreadSafeExample.subsubfield] -codetoanalyze/java/threadsafety/ThreadSafeMethods.java, Object ThreadSafeMethods.synchronizedReadOk(), 1, THREAD_SAFETY_VIOLATION, [access to codetoanalyze.java.checkers.ThreadSafeMethods.field5] codetoanalyze/java/threadsafety/ThreadSafeMethods.java, Object ThreadSafeMethods.threadSafeMethodReadBad(), 1, THREAD_SAFETY_VIOLATION, [access to codetoanalyze.java.checkers.ThreadSafeMethods.field2] codetoanalyze/java/threadsafety/ThreadSafeMethods.java, void ThreadSafeMethods.threadSafeMethodWriteBad(), 1, THREAD_SAFETY_VIOLATION, [access to codetoanalyze.java.checkers.ThreadSafeMethods.field1] codetoanalyze/java/threadsafety/ThreadSafeMethods.java, void ThreadSafeMethods.threadSafePrivateMethodBad(), 1, THREAD_SAFETY_VIOLATION, [access to codetoanalyze.java.checkers.ThreadSafeMethods.field2]