mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
java: fix aliasing FP
reorganise code, adding `LockField`
This commit is contained in:
@@ -184,16 +184,6 @@ module Monitors {
|
|||||||
locallySynchronizedOnClass(e, m.(ClassMonitor).getClassType())
|
locallySynchronizedOnClass(e, m.(ClassMonitor).getClassType())
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Holds if `localLock` refers to `lock`. */
|
|
||||||
predicate represents(Field lock, Variable localLock) {
|
|
||||||
lock.getType() instanceof LockType and
|
|
||||||
(
|
|
||||||
localLock = lock
|
|
||||||
or
|
|
||||||
localLock.getInitializer() = lock.getAnAccess()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets the control flow node that must dominate `e` when `e` is synchronized on a lock. */
|
/** Gets the control flow node that must dominate `e` when `e` is synchronized on a lock. */
|
||||||
ControlFlowNode getNodeToBeDominated(Expr e) {
|
ControlFlowNode getNodeToBeDominated(Expr e) {
|
||||||
// If `e` is the LHS of an assignment, use the control flow node for the assignment
|
// If `e` is the LHS of an assignment, use the control flow node for the assignment
|
||||||
@@ -204,15 +194,38 @@ module Monitors {
|
|||||||
result = e.getControlFlowNode()
|
result = e.getControlFlowNode()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A field storing a lock. */
|
||||||
|
class LockField extends Field {
|
||||||
|
LockField() { this.getType() instanceof LockType }
|
||||||
|
|
||||||
|
/** Gets a call to a method locking the lock stored in this field. */
|
||||||
|
MethodCall getLockCall() {
|
||||||
|
result.getQualifier() = this.getRepresentative().getAnAccess() and
|
||||||
|
result = this.getType().(LockType).getLockAccess()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets a call to a method unlocking the lock stored in this field. */
|
||||||
|
MethodCall getUnlockCall() {
|
||||||
|
result.getQualifier() = this.getRepresentative().getAnAccess() and
|
||||||
|
result = this.getType().(LockType).getUnlockAccess()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a variable representing this field.
|
||||||
|
* It can be the field itself or a local variable initialized to the field.
|
||||||
|
*/
|
||||||
|
private Variable getRepresentative() {
|
||||||
|
result = this
|
||||||
|
or
|
||||||
|
result.getInitializer() = this.getAnAccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Holds if `e` is synchronized on the `Lock` `lock` by a locking call. */
|
/** Holds if `e` is synchronized on the `Lock` `lock` by a locking call. */
|
||||||
predicate locallyLockedOn(Expr e, Field lock) {
|
predicate locallyLockedOn(Expr e, LockField lock) {
|
||||||
lock.getType() instanceof LockType and
|
exists(MethodCall lockCall, MethodCall unlockCall |
|
||||||
exists(Variable localLock, MethodCall lockCall, MethodCall unlockCall |
|
lockCall = lock.getLockCall() and
|
||||||
represents(lock, localLock) and
|
unlockCall = lock.getUnlockCall()
|
||||||
lockCall.getQualifier() = localLock.getAnAccess() and
|
|
||||||
lockCall = lock.getType().(LockType).getLockAccess() and
|
|
||||||
unlockCall.getQualifier() = localLock.getAnAccess() and
|
|
||||||
unlockCall = lock.getType().(LockType).getUnlockAccess()
|
|
||||||
|
|
|
|
||||||
dominates(lockCall.getControlFlowNode(), unlockCall.getControlFlowNode()) and
|
dominates(lockCall.getControlFlowNode(), unlockCall.getControlFlowNode()) and
|
||||||
dominates(lockCall.getControlFlowNode(), getNodeToBeDominated(e)) and
|
dominates(lockCall.getControlFlowNode(), getNodeToBeDominated(e)) and
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
| examples/Alias.java:16:13:16:13 | y | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/Alias.java:16:13:16:13 | y | this expression |
|
|
||||||
| examples/C.java:14:9:14:14 | this.y | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/C.java:14:9:14:14 | this.y | this expression |
|
| examples/C.java:14:9:14:14 | this.y | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/C.java:14:9:14:14 | this.y | this expression |
|
||||||
| examples/C.java:15:9:15:14 | this.y | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/C.java:15:9:15:14 | this.y | this expression |
|
| examples/C.java:15:9:15:14 | this.y | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/C.java:15:9:15:14 | this.y | this expression |
|
||||||
| examples/C.java:16:9:16:14 | this.y | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/C.java:16:9:16:14 | this.y | this expression |
|
| examples/C.java:16:9:16:14 | this.y | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/C.java:16:9:16:14 | this.y | this expression |
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public class Alias {
|
|||||||
final ReentrantLock lock = this.lock;
|
final ReentrantLock lock = this.lock;
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
y = 42; // $ SPURIOUS: Alert
|
y = 42;
|
||||||
} finally {
|
} finally {
|
||||||
this.lock.unlock();
|
this.lock.unlock();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user