@@ -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