Skip to content

Commit 01ddc11

Browse files
committed
java: address some review comments
1 parent 77734f8 commit 01ddc11

File tree

1 file changed

+23
-38
lines changed

1 file changed

+23
-38
lines changed

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

Lines changed: 23 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ module Monitors {
3737
abstract Location getLocation();
3838

3939
/** Gets a textual representation of this element. */
40-
string toString() { result = "Monitor" }
40+
abstract string toString();
4141
}
4242

4343
/**
@@ -46,50 +46,38 @@ module Monitors {
4646
* E.g `synchronized (m) { ... }` or `m.lock();`
4747
*/
4848
class VariableMonitor extends Monitor, TVariableMonitor {
49-
Variable v;
49+
override Location getLocation() { result = this.getVariable().getLocation() }
5050

51-
VariableMonitor() { this = TVariableMonitor(v) }
52-
53-
override Location getLocation() { result = v.getLocation() }
54-
55-
override string toString() { result = "VariableMonitor(" + v.toString() + ")" }
51+
override string toString() { result = "VariableMonitor(" + this.getVariable().toString() + ")" }
5652

5753
/** Gets the variable being used as a monitor. */
58-
Variable getVariable() { result = v }
54+
Variable getVariable() { this = TVariableMonitor(result) }
5955
}
6056

6157
/**
6258
* An instance reference used as a monitor.
6359
* Either via `synchronized (this) { ... }` or by marking a non-static method as `synchronized`.
6460
*/
6561
class InstanceMonitor extends Monitor, TInstanceMonitor {
66-
RefType thisType;
67-
68-
InstanceMonitor() { this = TInstanceMonitor(thisType) }
62+
override Location getLocation() { result = this.getThisType().getLocation() }
6963

70-
override Location getLocation() { result = thisType.getLocation() }
71-
72-
override string toString() { result = "InstanceMonitor(" + thisType.toString() + ")" }
64+
override string toString() { result = "InstanceMonitor(" + this.getThisType().toString() + ")" }
7365

7466
/** Gets the instance reference being used as a monitor. */
75-
RefType getThisType() { result = thisType }
67+
RefType getThisType() { this = TInstanceMonitor(result) }
7668
}
7769

7870
/**
7971
* A class used as a monitor.
8072
* This is achieved by marking a static method as `synchronized`.
8173
*/
8274
class ClassMonitor extends Monitor, TClassMonitor {
83-
RefType classType;
84-
85-
ClassMonitor() { this = TClassMonitor(classType) }
86-
87-
override Location getLocation() { result = classType.getLocation() }
75+
override Location getLocation() { result = this.getClassType().getLocation() }
8876

89-
override string toString() { result = "ClassMonitor(" + classType.toString() + ")" }
77+
override string toString() { result = "ClassMonitor(" + this.getClassType().toString() + ")" }
9078

9179
/** Gets the class being used as a monitor. */
92-
RefType getClassType() { result = classType }
80+
RefType getClassType() { this = TClassMonitor(result) }
9381
}
9482

9583
/** Holds if the expression `e` is synchronized on the monitor `m`. */
@@ -115,6 +103,15 @@ module Monitors {
115103
)
116104
}
117105

106+
ControlFlowNode getNodeToBeDominated(Expr e) {
107+
// If `e` is the LHS of an assignment, use the control flow node for the assignment
108+
exists(Assignment asgn | asgn.getDest() = e | result = asgn.getControlFlowNode())
109+
or
110+
// if `e` is not the LHS of an assignment, use the default control flow node
111+
not exists(Assignment asgn | asgn.getDest() = e) and
112+
result = e.getControlFlowNode()
113+
}
114+
118115
/** Holds if `e` is synchronized on the `Lock` `lock` by a locking call. */
119116
predicate locallyLockedOn(Expr e, Field lock) {
120117
isLockType(lock.getType()) and
@@ -126,8 +123,8 @@ module Monitors {
126123
unlockCall.getMethod().getName() = "unlock"
127124
|
128125
dominates(lockCall.getControlFlowNode(), unlockCall.getControlFlowNode()) and
129-
dominates(lockCall.getControlFlowNode(), e.getControlFlowNode()) and
130-
postDominates(unlockCall.getControlFlowNode(), e.getControlFlowNode())
126+
dominates(lockCall.getControlFlowNode(), getNodeToBeDominated(e)) and
127+
postDominates(unlockCall.getControlFlowNode(), getNodeToBeDominated(e))
131128
)
132129
}
133130
}
@@ -147,10 +144,9 @@ module Modification {
147144

148145
/** Holds if the call `c` modifies a shared resource. */
149146
predicate isModifyingCall(Call c) {
150-
exists(SummarizedCallable sc, string output, string prefix | sc.getACall() = c |
147+
exists(SummarizedCallable sc, string output | sc.getACall() = c |
151148
sc.propagatesFlow(_, output, _, _) and
152-
prefix = "Argument[this]" and
153-
output.prefix(prefix.length()) = prefix
149+
output.matches("Argument[this]%")
154150
)
155151
}
156152
}
@@ -200,17 +196,6 @@ class ExposedFieldAccess extends FieldAccess {
200196
// not the variable mention in a synchronized statement
201197
not this = any(SynchronizedStmt sync).getExpr()
202198
}
203-
204-
// LHS of assignments are excluded from the control flow graph,
205-
// so we use the control flow node for the assignment itself instead.
206-
override ControlFlowNode getControlFlowNode() {
207-
// this is the LHS of an assignment, use the control flow node for the assignment
208-
exists(Assignment asgn | asgn.getDest() = this | result = asgn.getControlFlowNode())
209-
or
210-
// this is not the LHS of an assignment, use the default control flow node
211-
not exists(Assignment asgn | asgn.getDest() = this) and
212-
result = super.getControlFlowNode()
213-
}
214199
}
215200

216201
/** Holds if the location of `a` is strictly before the location of `b`. */

0 commit comments

Comments
 (0)