[GuardedBy] Model of trylock in ReentrantLock.java

Summary:
The way interfaces are dealt with led to a false positive,
where tryLock() works OK for a Lock but not for a ReentrantLock.
The solution is just to provide the model.

While I am at it I am adding some more standard tests for Lock and ReentrantLock, which were not present.

Reviewed By: sblackshear

Differential Revision: D4204551

fbshipit-source-id: 9b6de28
master
Peter O'Hearn 8 years ago committed by Facebook Github Bot
parent 708c0bf1f8
commit f2d86cb90c

@ -19,6 +19,7 @@
*/ */
package java.util.concurrent.locks; package java.util.concurrent.locks;
import java.util.concurrent.TimeUnit;
import com.facebook.infer.builtins.InferBuiltins; import com.facebook.infer.builtins.InferBuiltins;
import com.facebook.infer.builtins.InferUndefined; import com.facebook.infer.builtins.InferUndefined;
@ -32,6 +33,41 @@ public abstract class ReentrantLock extends Lock implements java.io.Serializable
InferBuiltins.__set_locked_attribute(this); InferBuiltins.__set_locked_attribute(this);
} }
/**
Sometimes doesn't get a lock.
*/
public void lockInterruptibly() throws InterruptedException {
if (InferUndefined.boolean_undefined()) {
InferBuiltins.__set_locked_attribute(this);
} else {
throw new InterruptedException();
}
}
/**
Again, doesn't always succeed
*/
public boolean tryLock() {
if (InferUndefined.boolean_undefined()) {
InferBuiltins.__set_locked_attribute(this);
return true;
} else {
return false;
}
}
public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
if (InferUndefined.boolean_undefined()) {throw new InterruptedException();}
if (InferUndefined.boolean_undefined()) {
InferBuiltins.__set_locked_attribute(this);
return true;
} else {
return false;
}
}
/** /**
* In some implementations (like ReentrantLock) an exception is thrown if the lock * In some implementations (like ReentrantLock) an exception is thrown if the lock
* is not held by the current thread. This model does not consider that possibility. * is not held by the current thread. This model does not consider that possibility.

@ -50,6 +50,8 @@ src/infer/GuardedByExample.java, Object GuardedByExample.byRefTrickyBad(), 5, UN
src/infer/GuardedByExample.java, String GuardedByExample$3.readFromInnerClassBad1(), 2, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFromInnerClassBad1()] src/infer/GuardedByExample.java, String GuardedByExample$3.readFromInnerClassBad1(), 2, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFromInnerClassBad1()]
src/infer/GuardedByExample.java, String GuardedByExample$4.readFromInnerClassBad2(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFromInnerClassBad2()] src/infer/GuardedByExample.java, String GuardedByExample$4.readFromInnerClassBad2(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFromInnerClassBad2()]
src/infer/GuardedByExample.java, void GuardedByExample$Sub.badSub(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure badSub()] src/infer/GuardedByExample.java, void GuardedByExample$Sub.badSub(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure badSub()]
src/infer/GuardedByExample.java, void GuardedByExample.badGuardedByNormalLock(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure badGuardedByNormalLock()]
src/infer/GuardedByExample.java, void GuardedByExample.badGuardedByReentrantLock(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure badGuardedByReentrantLock()]
src/infer/GuardedByExample.java, void GuardedByExample.readFAfterBlockBad(), 3, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFAfterBlockBad()] src/infer/GuardedByExample.java, void GuardedByExample.readFAfterBlockBad(), 3, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFAfterBlockBad()]
src/infer/GuardedByExample.java, void GuardedByExample.readFBad(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBad()] src/infer/GuardedByExample.java, void GuardedByExample.readFBad(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBad()]
src/infer/GuardedByExample.java, void GuardedByExample.readFBadButSuppressedOther(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBadButSuppressedOther()] src/infer/GuardedByExample.java, void GuardedByExample.readFBadButSuppressedOther(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBadButSuppressedOther()]

@ -50,6 +50,8 @@ infer/tests/codetoanalyze/java/infer/GuardedByExample.java, Object GuardedByExam
infer/tests/codetoanalyze/java/infer/GuardedByExample.java, String GuardedByExample$3.readFromInnerClassBad1(), 2, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFromInnerClassBad1()] infer/tests/codetoanalyze/java/infer/GuardedByExample.java, String GuardedByExample$3.readFromInnerClassBad1(), 2, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFromInnerClassBad1()]
infer/tests/codetoanalyze/java/infer/GuardedByExample.java, String GuardedByExample$4.readFromInnerClassBad2(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFromInnerClassBad2()] infer/tests/codetoanalyze/java/infer/GuardedByExample.java, String GuardedByExample$4.readFromInnerClassBad2(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFromInnerClassBad2()]
infer/tests/codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample$Sub.badSub(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure badSub()] infer/tests/codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample$Sub.badSub(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure badSub()]
infer/tests/codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.badGuardedByNormalLock(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure badGuardedByNormalLock()]
infer/tests/codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.badGuardedByReentrantLock(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure badGuardedByReentrantLock()]
infer/tests/codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFAfterBlockBad(), 3, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFAfterBlockBad()] infer/tests/codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFAfterBlockBad(), 3, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFAfterBlockBad()]
infer/tests/codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFBad(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBad()] infer/tests/codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFBad(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBad()]
infer/tests/codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFBadButSuppressedOther(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBadButSuppressedOther()] infer/tests/codetoanalyze/java/infer/GuardedByExample.java, void GuardedByExample.readFBadButSuppressedOther(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBadButSuppressedOther()]

@ -16,6 +16,8 @@ import java.lang.annotation.Target;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import javax.annotation.concurrent.GuardedBy; import javax.annotation.concurrent.GuardedBy;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
@ -494,4 +496,43 @@ public class GuardedByExample {
} }
Lock normallock;
@GuardedBy("normallock")
Integer guardedbynl;
ReentrantLock reentrantlock;
@GuardedBy("reentrantlock")
Integer guardedbyrel;
void goodGuardedByNormalLock() {
normallock.lock();
guardedbynl = 22;
normallock.unlock();
}
void goodTryLockGuardedByNormalLock() {
if (normallock.tryLock()) {
guardedbynl = 22;
normallock.unlock();
}
}
void goodTryLockGuardedByReentrantLock() {
if (reentrantlock.tryLock()) {
guardedbyrel = 44;
reentrantlock.unlock();
}
}
void badGuardedByNormalLock(){
guardedbynl = 22;
}
void badGuardedByReentrantLock(){
guardedbyrel = 44;
}
} }

@ -129,6 +129,8 @@ GuardedByExample.java, Object GuardedByExample.byRefTrickyBad(), 5, UNSAFE_GUARD
GuardedByExample.java, String GuardedByExample$3.readFromInnerClassBad1(), 2, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFromInnerClassBad1()] GuardedByExample.java, String GuardedByExample$3.readFromInnerClassBad1(), 2, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFromInnerClassBad1()]
GuardedByExample.java, String GuardedByExample$4.readFromInnerClassBad2(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFromInnerClassBad2()] GuardedByExample.java, String GuardedByExample$4.readFromInnerClassBad2(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFromInnerClassBad2()]
GuardedByExample.java, void GuardedByExample$Sub.badSub(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure badSub()] GuardedByExample.java, void GuardedByExample$Sub.badSub(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure badSub()]
GuardedByExample.java, void GuardedByExample.badGuardedByNormalLock(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure badGuardedByNormalLock()]
GuardedByExample.java, void GuardedByExample.badGuardedByReentrantLock(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure badGuardedByReentrantLock()]
GuardedByExample.java, void GuardedByExample.readFAfterBlockBad(), 3, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFAfterBlockBad()] GuardedByExample.java, void GuardedByExample.readFAfterBlockBad(), 3, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFAfterBlockBad()]
GuardedByExample.java, void GuardedByExample.readFBad(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBad()] GuardedByExample.java, void GuardedByExample.readFBad(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBad()]
GuardedByExample.java, void GuardedByExample.readFBadButSuppressedOther(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBadButSuppressedOther()] GuardedByExample.java, void GuardedByExample.readFBadButSuppressedOther(), 1, UNSAFE_GUARDED_BY_ACCESS, [start of procedure readFBadButSuppressedOther()]

Loading…
Cancel
Save