|
| 1 | +/** |
| 2 | + * Finds usage of the object monitor lock for types implementing the `Condition` |
| 3 | + * or `Lock` interface. The object monitor lock is used by the `synchronized (...)` |
| 4 | + * statement and when calling the `Object` methods `notify`, `notifyAll` and `wait`. |
| 5 | + * Doing this on a `Condition` or `Lock` will most likely not work as desired |
| 6 | + * because those types might not be implemented using the object monitor lock. |
| 7 | + * Instead their dedicated methods should be used, such as `Condition.await()` or |
| 8 | + * `Lock.lock()`. |
| 9 | + * |
| 10 | + * This query is similar to the following SpotBug patterns: |
| 11 | + * - [DM_MONITOR_WAIT_ON_CONDITION](https://spotbugs.readthedocs.io/en/stable/bugDescriptions.html#dm-monitor-wait-called-on-condition-dm-monitor-wait-on-condition) |
| 12 | + * - [JML_JSR166_CALLING_WAIT_RATHER_THAN_AWAIT](https://spotbugs.readthedocs.io/en/stable/bugDescriptions.html#jlm-using-monitor-style-wait-methods-on-util-concurrent-abstraction-jml-jsr166-calling-wait-rather-than-await) |
| 13 | + * - [JLM_JSR166_LOCK_MONITORENTER](https://spotbugs.readthedocs.io/en/stable/bugDescriptions.html#jlm-synchronization-performed-on-lock-jlm-jsr166-lock-monitorenter) |
| 14 | + * |
| 15 | + * @kind problem |
| 16 | + */ |
| 17 | + |
| 18 | +// This extends CodeQL's query `java/wait-on-condition-interface` |
| 19 | + |
| 20 | +import java |
| 21 | + |
| 22 | +from Expr expr |
| 23 | +where |
| 24 | + expr.getType() |
| 25 | + .(RefType) |
| 26 | + .getASourceSupertype*() |
| 27 | + .hasQualifiedName("java.util.concurrent.locks", ["Condition", "Lock"]) and |
| 28 | + ( |
| 29 | + any(SynchronizedStmt s).getExpr() = expr |
| 30 | + or |
| 31 | + exists(MethodAccess call, Method m | |
| 32 | + call.getQualifier() = expr and |
| 33 | + m = call.getMethod() and |
| 34 | + m.getDeclaringType() instanceof TypeObject and |
| 35 | + m.hasName(["notify", "notifyAll", "wait"]) |
| 36 | + ) |
| 37 | + ) |
| 38 | + // Ignore if Condition or Lock implementation internally uses object monitor lock |
| 39 | + and not expr instanceof ThisAccess |
| 40 | +select expr, "Uses object monitor lock of " + expr.getType().getName() |
0 commit comments