Skip to content

Commit 406e48b

Browse files
committed
java: fix aliasing FP
reorganise code, adding `LockField`
1 parent 531b994 commit 406e48b

File tree

3 files changed

+32
-20
lines changed

3 files changed

+32
-20
lines changed

java/ql/lib/semmle/code/java/Concurrency.qll

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -184,16 +184,6 @@ module Monitors {
184184
locallySynchronizedOnClass(e, m.(ClassMonitor).getClassType())
185185
}
186186

187-
/** Holds if `localLock` refers to `lock`. */
188-
predicate represents(Field lock, Variable localLock) {
189-
lock.getType() instanceof LockType and
190-
(
191-
localLock = lock
192-
or
193-
localLock.getInitializer() = lock.getAnAccess()
194-
)
195-
}
196-
197187
/** Gets the control flow node that must dominate `e` when `e` is synchronized on a lock. */
198188
ControlFlowNode getNodeToBeDominated(Expr e) {
199189
// If `e` is the LHS of an assignment, use the control flow node for the assignment
@@ -204,15 +194,38 @@ module Monitors {
204194
result = e.getControlFlowNode()
205195
}
206196

197+
/** A field storing a lock. */
198+
class LockField extends Field {
199+
LockField() { this.getType() instanceof LockType }
200+
201+
/** Gets a call to a method locking the lock stored in this field. */
202+
MethodCall getLockCall() {
203+
result.getQualifier() = this.getRepresentative().getAnAccess() and
204+
result = this.getType().(LockType).getLockAccess()
205+
}
206+
207+
/** Gets a call to a method unlocking the lock stored in this field. */
208+
MethodCall getUnlockCall() {
209+
result.getQualifier() = this.getRepresentative().getAnAccess() and
210+
result = this.getType().(LockType).getUnlockAccess()
211+
}
212+
213+
/**
214+
* Gets a variable representing this field.
215+
* It can be the field itself or a local variable initialized to the field.
216+
*/
217+
private Variable getRepresentative() {
218+
result = this
219+
or
220+
result.getInitializer() = this.getAnAccess()
221+
}
222+
}
223+
207224
/** Holds if `e` is synchronized on the `Lock` `lock` by a locking call. */
208-
predicate locallyLockedOn(Expr e, Field lock) {
209-
lock.getType() instanceof LockType and
210-
exists(Variable localLock, MethodCall lockCall, MethodCall unlockCall |
211-
represents(lock, localLock) and
212-
lockCall.getQualifier() = localLock.getAnAccess() and
213-
lockCall = lock.getType().(LockType).getLockAccess() and
214-
unlockCall.getQualifier() = localLock.getAnAccess() and
215-
unlockCall = lock.getType().(LockType).getUnlockAccess()
225+
predicate locallyLockedOn(Expr e, LockField lock) {
226+
exists(MethodCall lockCall, MethodCall unlockCall |
227+
lockCall = lock.getLockCall() and
228+
unlockCall = lock.getUnlockCall()
216229
|
217230
dominates(lockCall.getControlFlowNode(), unlockCall.getControlFlowNode()) and
218231
dominates(lockCall.getControlFlowNode(), getNodeToBeDominated(e)) and

java/ql/test/query-tests/ThreadSafe/ThreadSafe.expected

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
| 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 |
21
| 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 |
32
| 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 |
43
| 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 |

java/ql/test/query-tests/ThreadSafe/examples/Alias.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public void notMismatch() {
1313
final ReentrantLock lock = this.lock;
1414
lock.lock();
1515
try {
16-
y = 42; // $ SPURIOUS: Alert
16+
y = 42;
1717
} finally {
1818
this.lock.unlock();
1919
}

0 commit comments

Comments
 (0)