[thread-safety] tests for thread-safe methods

Summary:
No new functionality here; mostly `FN_` tests documenting our current limitations.
Will start chipping away at the false negatives in follow-up diffs.

Reviewed By: peterogithub

Differential Revision: D4780013

fbshipit-source-id: 7a0c821
master
Sam Blackshear 8 years ago committed by Facebook Github Bot
parent a800908797
commit a5ee1f155c

@ -155,44 +155,3 @@ class YesThreadSafeExtendsNotThreadSafeExample extends NotThreadSafeExtendsThrea
} }
} }
class NonThreadSafeClass {
Object field;
@ThreadSafe
public void threadSafeMethod() {
this.field = new Object(); // should warn
}
@ThreadSafe
private void threadSafePrivateMethod() {
this.field = new Object(); // should warn
}
@ThreadSafe
@VisibleForTesting
public void threadSafeVisibleForTestingMethod() {
this.field = new Object(); // should warn
}
@ThreadSafe
public void safeMethod() {
}
}
class NonThreadSafeSubclass extends NonThreadSafeClass {
@Override
// overrides method annotated with @ThreadSafe, should warn
public void safeMethod() {
this.field = new Object();
}
// won't report this now, but should in the future. if a method annotated with @ThreadSafe
// in class C touches field f, then all other accesses to f in C must also be thread-safe
public void FN_touchesSameFieldAsThreadSafeMethod() {
this.field = new Object();
}
}

@ -0,0 +1,125 @@
/*
* Copyright (c) 2016 - 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.
*/
package codetoanalyze.java.checkers;
import com.facebook.infer.annotation.ThreadSafe;
import com.google.common.annotations.VisibleForTesting;
class ThreadSafeMethods {
Object field1;
Object field2;
Object field3;
Object field4;
Object field5;
@ThreadSafe
public void threadSafeMethodWriteBad() {
this.field1 = new Object(); // should warn
}
@ThreadSafe
public Object threadSafeMethodReadBad() {
return this.field2;
}
@ThreadSafe
private void threadSafePrivateMethodBad() {
this.field2 = new Object(); // should warn
}
@ThreadSafe
@VisibleForTesting
public void threadSafeVisibleForTestingMethodBad() {
this.field3 = new Object(); // should warn
}
@ThreadSafe
public void safeMethodOverride() {
}
// won't report this now, but should in the future. if a method annotated with @ThreadSafe
// in class C touches field f, then all other accesses to f in C must also be thread-safe
public void FN_writeSameFieldAsThreadSafeMethod1Bad() {
this.field1 = new Object();
}
// reads a field that is written in a method marked thread-safe
public Object FN_readSameFieldAsThreadSafeMethod1Bad() {
return this.field1;
}
public synchronized void safelyWriteSameFieldAsThreadSafeMethod1Ok() {
this.field1 = new Object();
}
public synchronized Object safelyReadSameFieldAsThreadSafeMethod1Ok() {
return this.field1;
}
@ThreadSafe
public synchronized void synchronizedWriteOk() {
this.field4 = new Object();
}
// unprotected write to a field that is written safely in a method marked thread-safe
public void FN_writeSameFieldAsThreadSafeMethod2Bad() {
this.field4 = new Object();
}
// unprotected read of a field that is written safely in a method marked thread-safe
public Object FN_readSameFieldAsThreadSafeMethod2Bad() {
return this.field4;
}
@ThreadSafe
public synchronized Object synchronizedReadOk() {
return this.field5;
}
// unprotected write to a field that is read safely in a method marked thread-safe
public void FN_writeSameFieldAsThreadSafeMethod3Bad() {
this.field5 = new Object();
}
// unprotected read of a field that is read safely in a method marked thread-safe
public Object FN_readSameFieldAsThreadSafeMethod3Bad() {
return this.field5;
}
}
class ThreadSafeMethodsSubclass extends ThreadSafeMethods {
Object subclassField;
@Override
// overrides method annotated with @ThreadSafe, should warn
public void safeMethodOverride() {
this.subclassField = new Object();
}
public void FN_writeThreadSafeFieldOfSuperclassBad() {
this.field1 = new Object();
}
public Object FN_readThreadSafeFieldOfSuperclassBad() {
return this.field1;
}
public void FN_writeThreadSafeFieldOfOverrideBad() {
this.subclassField = new Object();
}
public Object FN_readThreadSafeFieldOfOverrideBad() {
return this.subclassField;
}
}

@ -74,10 +74,6 @@ codetoanalyze/java/threadsafety/ReadWriteRaces.java, void ReadWriteRaces.readInC
codetoanalyze/java/threadsafety/ReadWriteRaces.java, void ReadWriteRaces.unprotectedWrite4Bad(), 1, THREAD_SAFETY_VIOLATION, [access to codetoanalyze.java.checkers.ReadWriteRaces.field4] codetoanalyze/java/threadsafety/ReadWriteRaces.java, void ReadWriteRaces.unprotectedWrite4Bad(), 1, THREAD_SAFETY_VIOLATION, [access to codetoanalyze.java.checkers.ReadWriteRaces.field4]
codetoanalyze/java/threadsafety/ThreadSafeExample.java, void ExtendsThreadSafeExample.newmethodBad(), 1, THREAD_SAFETY_VIOLATION, [access to codetoanalyze.java.checkers.ExtendsThreadSafeExample.field] codetoanalyze/java/threadsafety/ThreadSafeExample.java, void ExtendsThreadSafeExample.newmethodBad(), 1, THREAD_SAFETY_VIOLATION, [access to codetoanalyze.java.checkers.ExtendsThreadSafeExample.field]
codetoanalyze/java/threadsafety/ThreadSafeExample.java, void ExtendsThreadSafeExample.tsOK(), 1, THREAD_SAFETY_VIOLATION, [access to codetoanalyze.java.checkers.ExtendsThreadSafeExample.field] codetoanalyze/java/threadsafety/ThreadSafeExample.java, void ExtendsThreadSafeExample.tsOK(), 1, THREAD_SAFETY_VIOLATION, [access to codetoanalyze.java.checkers.ExtendsThreadSafeExample.field]
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 NonThreadSafeClass.threadSafePrivateMethod(), 1, THREAD_SAFETY_VIOLATION, [access to codetoanalyze.java.checkers.NonThreadSafeClass.field]
codetoanalyze/java/threadsafety/ThreadSafeExample.java, void NonThreadSafeClass.threadSafeVisibleForTestingMethod(), 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.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.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.deeperTraceBad(), 1, THREAD_SAFETY_VIOLATION, [call to void ThreadSafeExample.callAssignInPrivateMethod(),call to void ThreadSafeExample.assignInPrivateMethodOk(),access to codetoanalyze.java.checkers.ThreadSafeExample.f]
@ -85,3 +81,9 @@ 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.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 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/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]
codetoanalyze/java/threadsafety/ThreadSafeMethods.java, void ThreadSafeMethods.threadSafeVisibleForTestingMethodBad(), 1, THREAD_SAFETY_VIOLATION, [access to codetoanalyze.java.checkers.ThreadSafeMethods.field3]
codetoanalyze/java/threadsafety/ThreadSafeMethods.java, void ThreadSafeMethodsSubclass.safeMethodOverride(), 1, THREAD_SAFETY_VIOLATION, [access to codetoanalyze.java.checkers.ThreadSafeMethodsSubclass.subclassField]

Loading…
Cancel
Save