diff --git a/infer/src/checkers/ThreadSafety.ml b/infer/src/checkers/ThreadSafety.ml index d43e0eb2a..4aa96d7ec 100644 --- a/infer/src/checkers/ThreadSafety.ml +++ b/infer/src/checkers/ThreadSafety.ml @@ -1316,27 +1316,30 @@ let should_report_on_proc proc_desc tenv = let report_unsafe_accesses aggregated_access_map = let open ThreadSafetyDomain in let is_duplicate_report access pname {reported_sites; reported_writes; reported_reads} = - CallSite.Set.mem (TraceElem.call_site access) reported_sites - || - match TraceElem.kind access with - | Access.Write _ | Access.ContainerWrite _ - -> Typ.Procname.Set.mem pname reported_writes - | Access.Read _ | Access.ContainerRead _ - -> Typ.Procname.Set.mem pname reported_reads - | Access.InterfaceCall _ - -> false + if Config.filtering then CallSite.Set.mem (TraceElem.call_site access) reported_sites + || + match TraceElem.kind access with + | Access.Write _ | Access.ContainerWrite _ + -> Typ.Procname.Set.mem pname reported_writes + | Access.Read _ | Access.ContainerRead _ + -> Typ.Procname.Set.mem pname reported_reads + | Access.InterfaceCall _ + -> false + else false in let update_reported access pname reported = - let reported_sites = CallSite.Set.add (TraceElem.call_site access) reported.reported_sites in - match TraceElem.kind access with - | Access.Write _ | Access.ContainerWrite _ - -> let reported_writes = Typ.Procname.Set.add pname reported.reported_writes in - {reported with reported_writes; reported_sites} - | Access.Read _ | Access.ContainerRead _ - -> let reported_reads = Typ.Procname.Set.add pname reported.reported_reads in - {reported with reported_reads; reported_sites} - | Access.InterfaceCall _ - -> reported + if Config.filtering then + let reported_sites = CallSite.Set.add (TraceElem.call_site access) reported.reported_sites in + match TraceElem.kind access with + | Access.Write _ | Access.ContainerWrite _ + -> let reported_writes = Typ.Procname.Set.add pname reported.reported_writes in + {reported with reported_writes; reported_sites} + | Access.Read _ | Access.ContainerRead _ + -> let reported_reads = Typ.Procname.Set.add pname reported.reported_reads in + {reported with reported_reads; reported_sites} + | Access.InterfaceCall _ + -> reported + else reported in let report_unsafe_access (access, pre, threaded, tenv, pdesc) accesses reported_acc = let pname = Procdesc.get_proc_name pdesc in diff --git a/infer/tests/build_systems/threadsafety_dedup/Makefile b/infer/tests/build_systems/threadsafety_dedup/Makefile new file mode 100644 index 000000000..099132c27 --- /dev/null +++ b/infer/tests/build_systems/threadsafety_dedup/Makefile @@ -0,0 +1,17 @@ +# Copyright (c) 2017 - present Facebook, Inc. +# All rights reserved. +# +# This source code is licensed under the BSD style license found in the +# LICENSE file in the root directory of this source tree. An additional grant +# of patent rights can be found in the PATENTS file in the same directory. + +TESTS_DIR = ../.. + +ANALYZER = checkers + +INFER_OPTIONS = --project-root src --no-keep-going --threadsafety-only --filtering +INFERPRINT_OPTIONS = --issues-tests + +SOURCES = src/DeDup.java + +include $(TESTS_DIR)/javac.make diff --git a/infer/tests/build_systems/threadsafety_dedup/issues.exp b/infer/tests/build_systems/threadsafety_dedup/issues.exp new file mode 100644 index 000000000..870d53de5 --- /dev/null +++ b/infer/tests/build_systems/threadsafety_dedup/issues.exp @@ -0,0 +1,8 @@ +DeDup.java, void DeDup.colocated_read_write(), 1, THREAD_SAFETY_VIOLATION, [,call to void DeDup.read_and_write(),access to `build_systems.threadsafety.DeDup.colocated_read`,,access to `build_systems.threadsafety.DeDup.colocated_read`] +DeDup.java, void DeDup.separate_write_to_colocated_read(), 1, THREAD_SAFETY_VIOLATION, [access to `build_systems.threadsafety.DeDup.colocated_read`] +DeDup.java, void DeDup.twoWritesOneInCaller(), 2, THREAD_SAFETY_VIOLATION, [access to `build_systems.threadsafety.DeDup.field`] +DeDup.java, void DeDup.two_fields(), 1, THREAD_SAFETY_VIOLATION, [call to void DeDup.foo(),access to `build_systems.threadsafety.DeDup.fielda`] +DeDup.java, void DeDup.two_reads(), 3, THREAD_SAFETY_VIOLATION, [,access to `build_systems.threadsafety.DeDup.field`,,access to `build_systems.threadsafety.DeDup.field`] +DeDup.java, void DeDup.two_writes(), 2, THREAD_SAFETY_VIOLATION, [access to `build_systems.threadsafety.DeDup.field`] +DeDup.java, void DeDup.write_read(), 2, THREAD_SAFETY_VIOLATION, [access to `build_systems.threadsafety.DeDup.field`] +DeDup.java, void DeDup.write_read(), 3, THREAD_SAFETY_VIOLATION, [,access to `build_systems.threadsafety.DeDup.field`,,access to `build_systems.threadsafety.DeDup.field`] diff --git a/infer/tests/codetoanalyze/java/threadsafety/DeDup.java b/infer/tests/build_systems/threadsafety_dedup/src/DeDup.java similarity index 97% rename from infer/tests/codetoanalyze/java/threadsafety/DeDup.java rename to infer/tests/build_systems/threadsafety_dedup/src/DeDup.java index b72635e29..054839cf4 100644 --- a/infer/tests/codetoanalyze/java/threadsafety/DeDup.java +++ b/infer/tests/build_systems/threadsafety_dedup/src/DeDup.java @@ -7,7 +7,7 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -package codetoanalyze.java.checkers; +package build_systems.threadsafety; import javax.annotation.concurrent.ThreadSafe; diff --git a/infer/tests/codetoanalyze/java/threadsafety/issues.exp b/infer/tests/codetoanalyze/java/threadsafety/issues.exp index 94cabb88e..21ed2d67a 100644 --- a/infer/tests/codetoanalyze/java/threadsafety/issues.exp +++ b/infer/tests/codetoanalyze/java/threadsafety/issues.exp @@ -45,14 +45,6 @@ codetoanalyze/java/threadsafety/Containers.java, void Containers.mapPutBad(Strin codetoanalyze/java/threadsafety/Containers.java, void Containers.mapRemoveBad(String), 1, THREAD_SAFETY_VIOLATION, [Write to container `&this.codetoanalyze.java.checkers.Containers.mMap` via call to `remove`] codetoanalyze/java/threadsafety/Containers.java, void Containers.mapSubclassWriteBad(HashMap,String), 1, THREAD_SAFETY_VIOLATION, [Write to container `&m` via call to `remove`] codetoanalyze/java/threadsafety/Containers.java, void Containers.poolBad(), 5, THREAD_SAFETY_VIOLATION, [Write to container `&this.codetoanalyze.java.checkers.Containers.simplePool` via call to `release`] -codetoanalyze/java/threadsafety/DeDup.java, void DeDup.colocated_read_write(), 1, THREAD_SAFETY_VIOLATION, [,call to void DeDup.read_and_write(),access to `codetoanalyze.java.checkers.DeDup.colocated_read`,,access to `codetoanalyze.java.checkers.DeDup.colocated_read`] -codetoanalyze/java/threadsafety/DeDup.java, void DeDup.separate_write_to_colocated_read(), 1, THREAD_SAFETY_VIOLATION, [access to `codetoanalyze.java.checkers.DeDup.colocated_read`] -codetoanalyze/java/threadsafety/DeDup.java, void DeDup.twoWritesOneInCaller(), 2, THREAD_SAFETY_VIOLATION, [access to `codetoanalyze.java.checkers.DeDup.field`] -codetoanalyze/java/threadsafety/DeDup.java, void DeDup.two_fields(), 1, THREAD_SAFETY_VIOLATION, [call to void DeDup.foo(),access to `codetoanalyze.java.checkers.DeDup.fielda`] -codetoanalyze/java/threadsafety/DeDup.java, void DeDup.two_reads(), 3, THREAD_SAFETY_VIOLATION, [,access to `codetoanalyze.java.checkers.DeDup.field`,,access to `codetoanalyze.java.checkers.DeDup.field`] -codetoanalyze/java/threadsafety/DeDup.java, void DeDup.two_writes(), 2, THREAD_SAFETY_VIOLATION, [access to `codetoanalyze.java.checkers.DeDup.field`] -codetoanalyze/java/threadsafety/DeDup.java, void DeDup.write_read(), 2, THREAD_SAFETY_VIOLATION, [access to `codetoanalyze.java.checkers.DeDup.field`] -codetoanalyze/java/threadsafety/DeDup.java, void DeDup.write_read(), 3, THREAD_SAFETY_VIOLATION, [,access to `codetoanalyze.java.checkers.DeDup.field`,,access to `codetoanalyze.java.checkers.DeDup.field`] codetoanalyze/java/threadsafety/Dispatch.java, void Dispatch.callUnannotatedInterfaceBad(UnannotatedInterface), 1, THREAD_SAFETY_VIOLATION, [Call to un-annotated interface method void UnannotatedInterface.foo()1] codetoanalyze/java/threadsafety/Dispatch.java, void Dispatch.callUnannotatedInterfaceIndirectBad(NotThreadSafe,UnannotatedInterface), 1, THREAD_SAFETY_VIOLATION, [call to void NotThreadSafe.notThreadSafeOk(UnannotatedInterface),Call to un-annotated interface method void UnannotatedInterface.foo()1] codetoanalyze/java/threadsafety/Locks.java, void Locks.FP_unlockOneLock(), 4, THREAD_SAFETY_VIOLATION, [access to `codetoanalyze.java.checkers.Locks.f`]