java: rewrite conflict detection

- favour unary predicates over binary ones
(the natural "conflicting access" is binary)
- switch to a dual solution to trade recursion through forall for simple existentials.

Co-authored-by: Anders Schack-Mulligen <aschackmull@github.com>
This commit is contained in:
yoff
2025-10-17 01:39:29 +02:00
parent 5109babd92
commit 61a3e9630f
11 changed files with 296 additions and 323 deletions

View File

@@ -44,7 +44,11 @@ predicate isThreadSafeType(Type t) {
/** Holds if the expression `e` is a thread-safe initializer. */
predicate isThreadSafeInitializer(Expr e) {
e.(Call).getCallee().getQualifiedName().matches("java.util.Collections.synchronized%")
e.(Call)
.getCallee()
.getSourceDeclaration()
.getQualifiedName()
.matches("java.util.Collections.synchronized%")
}
/**
@@ -84,17 +88,6 @@ class ExposedFieldAccess extends FieldAccess {
}
}
/** Holds if the location of `a` is strictly before the location of `b`. */
bindingset[a, b]
overlay[caller?]
pragma[inline_late]
predicate orderedLocations(Location a, Location b) {
a.getStartLine() < b.getStartLine()
or
a.getStartLine() = b.getStartLine() and
a.getStartColumn() < b.getStartColumn()
}
/**
* A class annotated as `@ThreadSafe`.
* Provides predicates to check for concurrency issues.
@@ -102,213 +95,192 @@ predicate orderedLocations(Location a, Location b) {
class ClassAnnotatedAsThreadSafe extends Class {
ClassAnnotatedAsThreadSafe() { this.getAnAnnotation().getType().getName() = "ThreadSafe" }
/** Holds if `a` and `b` are conflicting accesses to the same field and not monitored by the same monitor. */
predicate unsynchronised(ExposedFieldAccess a, ExposedFieldAccess b) {
this.conflicting(a, b) and
this.publicAccess(_, a) and
this.publicAccess(_, b) and
not exists(Monitors::Monitor m |
this.monitors(a, m) and
this.monitors(b, m)
)
}
/** Holds if `a` is the earliest write to its field that is unsynchronized with `b`. */
predicate unsynchronised_normalized(ExposedFieldAccess a, ExposedFieldAccess b) {
this.unsynchronised(a, b) and
// Eliminate double reporting by making `a` the earliest write to this field
// that is unsynchronized with `b`.
not exists(ExposedFieldAccess earlier_a |
earlier_a.getField() = a.getField() and
orderedLocations(earlier_a.getLocation(), a.getLocation())
|
this.unsynchronised(earlier_a, b)
)
}
// We wish to find conflicting accesses that are reachable from public methods
// and to know which monitors protect them.
//
// It is very easy and natural to write a predicate for conflicting accesses,
// but that would be binary, and hence not suited for reachability analysis.
//
// It is also easy to state that all accesses to a field are protected by a single monitor,
// but that would require a forall, which is not suited for recursion.
// (The recursion occurs for example as you traverse the access path and keep requiring that all tails are protected.)
//
// We therefore use a dual solution:
// - We write a unary recursive predicate for accesses that are not protected by any monitor.
// Any such write access, reachable from a public method, is conflicting with itself.
// And any such read will be conflicting with any publicly reachable write access (locked or not).
//
// - We project the above predicate down to fields, so we can find fields with unprotected accesses.
// - From this we can derive a unary recursive predicate for fields whose accesses are protected by exactly one monitor.
// The predicate tracks the monitor.
// If such a field has two accesses protected by different monitors, we have a concurrency issue.
// This can be determined by simple counting at the end of the recursion.
// Technically, we only have a concurrency issue if there is a write access,
// but if you are locking your reads with different locks, you likely made a typo.
//
// - From the above, we can derive a unary recursive predicate for fields whose accesses are protected by at least one monitor.
// This predicate tracks all the monitors that protect accesses to the field.
// This is combined with a predicate that checks if any access escapes a given monitor.
// If all the monitors that protect accesses to a field are escaped by at least one access,
// we have a concurrency issue.
// This can be determined by a single forall at the end of the recursion.
//
// With this formulation we avoid binary predicates and foralls in recursion.
//
// Cases where a field access is not protected by any monitor
/**
* Holds if `a` and `b` are unsynchronized and both publicly accessible
* as witnessed by `witness_a` and `witness_b`.
* Holds if the field access `a` to the field `f` is not protected by any monitor, and it can be reached via the expression `e` in the method `m`.
* We maintain the invariant that `m = e.getEnclosingCallable()`.
*/
predicate witness(ExposedFieldAccess a, Expr witness_a, ExposedFieldAccess b, Expr witness_b) {
this.unsynchronised_normalized(a, b) and
this.publicAccess(witness_a, a) and
this.publicAccess(witness_b, b) and
// avoid double reporting
not exists(Expr better_witness_a | this.publicAccess(better_witness_a, a) |
orderedLocations(better_witness_a.getLocation(), witness_a.getLocation())
) and
not exists(Expr better_witness_b | this.publicAccess(better_witness_b, b) |
orderedLocations(better_witness_b.getLocation(), witness_b.getLocation())
)
}
/**
* Actions `a` and `b` are conflicting iff
* they are field access operations on the same field and
* at least one of them is a write.
*/
predicate conflicting(ExposedFieldAccess a, ExposedFieldAccess b) {
// We allow a = b, since they could be executed on different threads
// We are looking for two operations:
// - on the same non-volatile field
a.getField() = b.getField() and
// - on this class
a.getField() = this.getAField() and
// - where at least one is a write
// wlog we assume that is `a`
// We use a slightly more inclusive definition than simply `a.isVarWrite()`
Modification::isModifying(a) and
// Avoid reporting both `(a, b)` and `(b, a)` by choosing the tuple
// where `a` appears before `b` in the source code.
predicate unlocked_access(ExposedField f, Expr e, Method m, ExposedFieldAccess a, boolean write) {
m.getDeclaringType() = this and
(
(
Modification::isModifying(b) and
a != b
)
implies
orderedLocations(a.getLocation(), b.getLocation())
)
}
/** Holds if `a` can be reached by a path from a public method, and all such paths are monitored by `monitor`. */
predicate monitors(ExposedFieldAccess a, Monitors::Monitor monitor) {
forex(Method m | this.providesAccess(m, _, a) and m.isPublic() |
this.monitorsVia(m, a, monitor)
)
}
/** Holds if `a` can be reached by a path from a public method and `e` is the expression in that method that starts the path. */
predicate publicAccess(Expr e, ExposedFieldAccess a) {
exists(Method m | m.isPublic() | this.providesAccess(m, e, a))
}
/**
* Holds if a call to method `m` can cause an access of `a` and `e` is the expression inside `m` that leads to that access.
* `e` will either be `a` itself or a method call that leads to `a`.
*/
predicate providesAccess(Method m, Expr e, ExposedFieldAccess a) {
m = this.getAMethod() and
(
a.getEnclosingCallable() = m and
e = a
// base case
f.getDeclaringType() = this and
m = e.getEnclosingCallable() and
a.getField() = f and
a = e and
(if Modification::isModifying(a) then write = true else write = false)
or
exists(MethodCall c | c.getEnclosingCallable() = m |
this.providesAccess(c.getCallee(), _, a) and
e = c
// recursive case
exists(MethodCall c, Expr e0, Method m0 | this.unlocked_access(f, e0, m0, a, write) |
m = c.getEnclosingCallable() and
not m0.isPublic() and
c.getCallee().getSourceDeclaration() = m0 and
c = e and
not Monitors::locallyMonitors(e0, _)
)
)
}
// NOTE:
// In order to deal with loops in the call graph, we compute the strongly connected components (SCCs).
// We only wish to do this for the methods that can lead to exposed field accesses.
// Given a field access `a`, we can consider a "call graph of interest", a sub graph of the call graph
// that only contains methods that lead to an access of `a`. We call this "the call graph induced by `a`".
// We can then compute the SCCs of this graph, yielding the SCC graph induced by `a`.
/** Holds if the class has an unlocked access to the field `f` via the expression `e` in the method `m`. */
predicate has_unlocked_access(ExposedField f, Expr e, Method m, boolean write) {
this.unlocked_access(f, e, m, _, write)
}
/** Holds if the field access `a` to the field `f` is not protected by any monitor, and it can be reached via the expression `e` in the public method `m`. */
predicate unlocked_public_access(
ExposedField f, Expr e, Method m, ExposedFieldAccess a, boolean write
) {
this.unlocked_access(f, e, m, a, write) and
m.isPublic() and
not Monitors::locallyMonitors(e, _)
}
/** Holds if the class has an unlocked access to the field `f` via the expression `e` in the public method `m`. */
predicate has_unlocked_public_access(ExposedField f, Expr e, Method m, boolean write) {
this.unlocked_public_access(f, e, m, _, write)
}
// Cases where all accesses to a field are protected by exactly one monitor
//
/**
* Holds if a call to method `m` can cause an access of `a` by `m` calling `callee`.
* This is an edge in the call graph induced by `a`.
* Holds if the class has an access, locked by exactly one monitor, to the field `f` via the expression `e` in the method `m`.
*/
predicate accessVia(Method m, ExposedFieldAccess a, Method callee) {
exists(MethodCall c | this.providesAccess(m, c, a) | callee = c.getCallee())
}
/** Holds if `m` can reach `reached` by a path in the call graph induced by `a`. */
predicate accessReach(Method m, ExposedFieldAccess a, Method reached) {
m = this.getAMethod() and
reached = this.getAMethod() and
this.providesAccess(m, _, a) and
this.providesAccess(reached, _, a) and
(
this.accessVia(m, a, reached)
or
exists(Method mid | this.accessReach(m, a, mid) | this.accessVia(mid, a, reached))
)
}
/**
* Holds if `rep` is a representative of the SCC containing `m` in the call graph induced by `a`.
* This only assigns representatives to methods involved in loops.
* To get a representative of any method, use `repScc`.
*/
predicate repInLoopScc(Method rep, ExposedFieldAccess a, Method m) {
// `rep` and `m` are in the same SCC
this.accessReach(rep, a, m) and
this.accessReach(m, a, rep) and
// `rep` is the representative of the SCC
// that is, the earliest in the source code
forall(Method alt_rep |
rep != alt_rep and
this.accessReach(alt_rep, a, m) and
this.accessReach(m, a, alt_rep)
|
rep.getLocation().getStartLine() < alt_rep.getLocation().getStartLine()
)
}
/** Holds if `rep` is a representative of the SCC containing `m` in the call graph induced by `a`. */
predicate repScc(Method rep, ExposedFieldAccess a, Method m) {
this.repInLoopScc(rep, a, m)
predicate has_onelocked_access(
ExposedField f, Expr e, Method m, boolean write, Monitors::Monitor monitor
) {
//base
this.has_unlocked_access(f, e, m, write) and
Monitors::locallyMonitors(e, monitor)
or
// If `m` is in the call graph induced by `a` and did not get a representative from `repInLoopScc`,
// it is represented by itself.
m = this.getAMethod() and
this.providesAccess(m, _, a) and
not this.repInLoopScc(_, a, m) and
rep = m
// recursive case
exists(MethodCall c, Expr e0, Method m0 | this.has_onelocked_access(f, e0, m0, write, monitor) |
m = c.getEnclosingCallable() and
not m0.isPublic() and
c.getCallee().getSourceDeclaration() = m0 and
c = e and
// consider allowing idempotent monitors
not Monitors::locallyMonitors(e, _) and
m.getDeclaringType() = this
)
}
/**
* Holds if `c` is a call from the SCC represented by `callerRep` to the (different) SCC represented by `calleeRep`.
* This is an edge in the SCC graph induced by `a`.
*/
predicate callEdgeScc(Method callerRep, ExposedFieldAccess a, MethodCall c, Method calleeRep) {
callerRep != calleeRep and
exists(Method caller, Method callee |
this.repScc(callerRep, a, caller) and
this.repScc(calleeRep, a, callee)
/** Holds if the class has an access, locked by exactly one monitor, to the field `f` via the expression `e` in the public method `m`. */
predicate has_onelocked_public_access(
ExposedField f, Expr e, Method m, boolean write, Monitors::Monitor monitor
) {
this.has_onelocked_access(f, e, m, write, monitor) and
m.isPublic() and
not this.has_unlocked_public_access(f, e, m, write)
}
/** Holds if the field `f` has more than one access, all locked by a single monitor, but different monitors are used. */
predicate single_monitor_mismatch(ExposedField f) {
2 <=
strictcount(Monitors::Monitor monitor | this.has_onelocked_public_access(f, _, _, _, monitor))
}
// Cases where all accesses to a field are protected by at least one monitor
//
/** Holds if the class has an access, locked by at least one monitor, to the field `f` via the expression `e` in the method `m`. */
predicate has_onepluslocked_access(
ExposedField f, Expr e, Method m, boolean write, Monitors::Monitor monitor
) {
//base
this.has_onelocked_access(f, e, m, write, monitor) and
not this.single_monitor_mismatch(f) and
not this.has_unlocked_public_access(f, _, _, _)
or
// recursive case
exists(MethodCall c, Expr e0, Method m0, Monitors::Monitor monitor0 |
this.has_onepluslocked_access(f, e0, m0, write, monitor0) and
m = c.getEnclosingCallable() and
not m0.isPublic() and
c.getCallee().getSourceDeclaration() = m0 and
c = e and
m.getDeclaringType() = this
|
this.accessVia(caller, a, callee) and
c.getEnclosingCallable() = caller and
c.getCallee() = callee
)
}
/**
* Holds if the SCC represented by `rep` can cause an access to `a` and `e` is the expression that leads to that access.
* `e` will either be `a` itself or a method call that leads to `a` via a different SCC.
*/
predicate providesAccessScc(Method rep, Expr e, ExposedFieldAccess a) {
rep = this.getAMethod() and
exists(Method m | this.repScc(rep, a, m) |
a.getEnclosingCallable() = m and
e = a
monitor = monitor0
or
exists(MethodCall c | this.callEdgeScc(rep, a, c, _) | e = c)
Monitors::locallyMonitors(e, monitor)
)
}
/** Holds if all paths from `rep` to `a` are monitored by `monitor`. */
predicate monitorsViaScc(Method rep, ExposedFieldAccess a, Monitors::Monitor monitor) {
rep = this.getAMethod() and
this.providesAccessScc(rep, _, a) and
// If we are in an SCC that can access `a`, the access must be monitored locally
(this.repScc(rep, a, a.getEnclosingCallable()) implies Monitors::locallyMonitors(a, monitor)) and
// Any call towards `a` must either be monitored or guarantee that the access is monitored
forall(MethodCall c, Method calleeRep | this.callEdgeScc(rep, a, c, calleeRep) |
Monitors::locallyMonitors(c, monitor)
or
this.monitorsViaScc(calleeRep, a, monitor)
/** Holds if the class has a write access to the field `f` that can be reached via a public method. */
predicate has_public_write_access(ExposedField f) {
this.has_unlocked_public_access(f, _, _, true)
or
this.has_onelocked_public_access(f, _, _, true, _)
or
exists(Method m | m.getDeclaringType() = this and m.isPublic() |
this.has_onepluslocked_access(f, _, m, true, _)
)
}
/** Holds if all paths from `m` to `a` are monitored by `monitor`. */
predicate monitorsVia(Method m, ExposedFieldAccess a, Monitors::Monitor monitor) {
exists(Method rep |
this.repScc(rep, a, m) and
this.monitorsViaScc(rep, a, monitor)
/** Holds if the class has an access, not protected by the monitor `m`, to the field `f` via the expression `e` in the method `m`. */
predicate escapes_monitor(
ExposedField f, Expr e, Method m, boolean write, Monitors::Monitor monitor
) {
//base
this.has_onepluslocked_access(f, _, _, _, monitor) and
this.has_unlocked_access(f, e, m, write) and
not Monitors::locallyMonitors(e, monitor)
or
// recursive case
exists(MethodCall c, Expr e0, Method m0 | this.escapes_monitor(f, e0, m0, write, monitor) |
m = c.getEnclosingCallable() and
not m0.isPublic() and
c.getCallee().getSourceDeclaration() = m0 and
c = e and
// consider allowing idempotent monitors
not Monitors::locallyMonitors(e, monitor) and
m.getDeclaringType() = this
)
}
/** Holds if the class has an access, not protected by the monitor `m`, to the field `f` via the expression `e` in the public method `m`. */
predicate escapes_monitor_public(
ExposedField f, Expr e, Method m, boolean write, Monitors::Monitor monitor
) {
this.escapes_monitor(f, e, m, write, monitor) and
m.isPublic()
}
/** Holds if no monitor protects all accesses to the field `f`. */
predicate not_fully_monitored(ExposedField f) {
forex(Monitors::Monitor monitor | this.has_onepluslocked_access(f, _, _, _, monitor) |
this.escapes_monitor_public(f, _, _, _, monitor)
)
}
}

View File

@@ -14,13 +14,43 @@
import java
import semmle.code.java.ConflictingAccess
predicate unmonitored_access(
ClassAnnotatedAsThreadSafe cls, ExposedFieldAccess a, Expr entry, string msg, string entry_desc
) {
exists(ExposedField f |
cls.unlocked_public_access(f, entry, _, a, true)
or
cls.unlocked_public_access(f, entry, _, a, false) and
cls.has_public_write_access(f)
) and
msg =
"This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe." and
entry_desc = "this expression"
}
predicate not_fully_monitored_field(
ClassAnnotatedAsThreadSafe cls, ExposedField f, string msg, string cls_name
) {
(
// Technically there has to be a write access for a conflict to exist.
// But if you are locking your reads with different locks, you likely made a typo,
// so in this case we alert without requiring `cls.has_public_write_access(f)`
cls.single_monitor_mismatch(f)
or
cls.not_fully_monitored(f) and
cls.has_public_write_access(f)
) and
msg =
"The field $@ is not properly synchronized in that no single monitor covers all accesses, but the class $@ is annotated as @ThreadSafe." and
cls_name = cls.getName()
}
from
ClassAnnotatedAsThreadSafe cls, FieldAccess modifyingAccess, Expr witness_modifyingAccess,
FieldAccess conflictingAccess, Expr witness_conflictingAccess
ClassAnnotatedAsThreadSafe cls, Top alert_element, Top alert_context, string alert_msg,
string context_desc
where
cls.witness(modifyingAccess, witness_modifyingAccess, conflictingAccess, witness_conflictingAccess)
select modifyingAccess,
"This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor.",
witness_modifyingAccess, "this expression", conflictingAccess, "this field access",
witness_conflictingAccess, "this expression"
// select c, a.getField()
unmonitored_access(cls, alert_element, alert_context, alert_msg, context_desc)
or
not_fully_monitored_field(cls, alert_element, alert_msg, context_desc) and
alert_context = cls
select alert_element, alert_msg, alert_context, context_desc

View File

@@ -1,72 +1,43 @@
| examples/C.java:14:9:14:14 | this.y | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/C.java:14:9:14:14 | this.y | this expression | examples/C.java:14:9:14:14 | this.y | this field access | examples/C.java:14:9:14:14 | this.y | this expression |
| examples/C.java:14:9:14:14 | this.y | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/C.java:14:9:14:14 | this.y | this expression | examples/C.java:15:9:15:14 | this.y | this field access | examples/C.java:15:9:15:14 | this.y | this expression |
| examples/C.java:14:9:14:14 | this.y | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/C.java:14:9:14:14 | this.y | this expression | examples/C.java:16:9:16:14 | this.y | this field access | examples/C.java:16:9:16:14 | this.y | this expression |
| examples/C.java:14:9:14:14 | this.y | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/C.java:14:9:14:14 | this.y | this expression | examples/C.java:16:18:16:23 | this.y | this field access | examples/C.java:16:18:16:23 | this.y | this expression |
| examples/C.java:14:9:14:14 | this.y | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/C.java:14:9:14:14 | this.y | this expression | examples/C.java:20:9:20:14 | this.y | this field access | examples/C.java:20:9:20:14 | this.y | this expression |
| examples/C.java:14:9:14:14 | this.y | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/C.java:14:9:14:14 | this.y | this expression | examples/C.java:21:9:21:14 | this.y | this field access | examples/C.java:21:9:21:14 | this.y | this expression |
| examples/C.java:14:9:14:14 | this.y | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/C.java:14:9:14:14 | this.y | this expression | examples/C.java:22:9:22:14 | this.y | this field access | examples/C.java:22:9:22:14 | this.y | this expression |
| examples/C.java:14:9:14:14 | this.y | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/C.java:14:9:14:14 | this.y | this expression | examples/C.java:22:18:22:23 | this.y | this field access | examples/C.java:22:18:22:23 | this.y | this expression |
| examples/C.java:14:9:14:14 | this.y | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/C.java:14:9:14:14 | this.y | this expression | examples/C.java:26:9:26:14 | this.y | this field access | examples/C.java:26:9:26:14 | this.y | this expression |
| examples/C.java:14:9:14:14 | this.y | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/C.java:14:9:14:14 | this.y | this expression | examples/C.java:30:13:30:13 | y | this field access | examples/C.java:30:13:30:13 | y | this expression |
| examples/C.java:14:9:14:14 | this.y | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/C.java:14:9:14:14 | this.y | this expression | examples/C.java:33:9:33:9 | y | this field access | examples/C.java:33:9:33:9 | y | this expression |
| examples/C.java:14:9:14:14 | this.y | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/C.java:14:9:14:14 | this.y | this expression | examples/C.java:39:9:39:14 | this.y | this field access | examples/C.java:39:9:39:14 | this.y | this expression |
| examples/C.java:14:9:14:14 | this.y | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/C.java:14:9:14:14 | this.y | this expression | examples/C.java:40:9:40:14 | this.y | this field access | examples/C.java:40:9:40:14 | this.y | this expression |
| examples/C.java:14:9:14:14 | this.y | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/C.java:14:9:14:14 | this.y | this expression | examples/C.java:41:9:41:14 | this.y | this field access | examples/C.java:41:9:41:14 | this.y | this expression |
| examples/C.java:14:9:14:14 | this.y | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/C.java:14:9:14:14 | this.y | this expression | examples/C.java:41:18:41:23 | this.y | this field access | examples/C.java:41:18:41:23 | this.y | this expression |
| examples/C.java:14:9:14:14 | this.y | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/C.java:14:9:14:14 | this.y | this expression | examples/C.java:53:9:53:14 | this.y | this field access | examples/C.java:53:9:53:14 | this.y | this expression |
| examples/C.java:14:9:14:14 | this.y | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/C.java:14:9:14:14 | this.y | this expression | examples/C.java:54:9:54:14 | this.y | this field access | examples/C.java:54:9:54:14 | this.y | this expression |
| examples/C.java:14:9:14:14 | this.y | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/C.java:14:9:14:14 | this.y | this expression | examples/C.java:55:9:55:14 | this.y | this field access | examples/C.java:55:9:55:14 | this.y | this expression |
| examples/C.java:14:9:14:14 | this.y | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/C.java:14:9:14:14 | this.y | this expression | examples/C.java:55:18:55:23 | this.y | this field access | examples/C.java:55:18:55:23 | this.y | this expression |
| examples/C.java:14:9:14:14 | this.y | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/C.java:14:9:14:14 | this.y | this expression | examples/C.java:61:9:61:9 | y | this field access | examples/C.java:61:9:61:9 | y | this expression |
| examples/C.java:14:9:14:14 | this.y | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/C.java:14:9:14:14 | this.y | this expression | examples/C.java:62:9:62:9 | y | this field access | examples/C.java:62:9:62:9 | y | this expression |
| examples/C.java:14:9:14:14 | this.y | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/C.java:14:9:14:14 | this.y | this expression | examples/C.java:63:9:63:9 | y | this field access | examples/C.java:63:9:63:9 | y | this expression |
| examples/C.java:14:9:14:14 | this.y | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/C.java:14:9:14:14 | this.y | this expression | examples/C.java:63:13:63:13 | y | this field access | examples/C.java:63:13:63:13 | y | this expression |
| examples/FaultyTurnstileExample.java:13:5:13:9 | count | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/FaultyTurnstileExample.java:13:5:13:9 | count | this expression | examples/FaultyTurnstileExample.java:18:5:18:9 | count | this field access | examples/FaultyTurnstileExample.java:18:5:18:9 | count | this expression |
| examples/FaultyTurnstileExample.java:30:5:30:9 | count | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/FaultyTurnstileExample.java:30:5:30:9 | count | this expression | examples/FaultyTurnstileExample.java:36:5:36:9 | count | this field access | examples/FaultyTurnstileExample.java:36:5:36:9 | count | this expression |
| examples/FlawedSemaphore.java:18:7:18:11 | state | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/FlawedSemaphore.java:18:7:18:11 | state | this expression | examples/FlawedSemaphore.java:15:14:15:18 | state | this field access | examples/FlawedSemaphore.java:15:14:15:18 | state | this expression |
| examples/FlawedSemaphore.java:18:7:18:11 | state | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/FlawedSemaphore.java:18:7:18:11 | state | this expression | examples/FlawedSemaphore.java:18:7:18:11 | state | this field access | examples/FlawedSemaphore.java:18:7:18:11 | state | this expression |
| examples/FlawedSemaphore.java:18:7:18:11 | state | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/FlawedSemaphore.java:18:7:18:11 | state | this expression | examples/FlawedSemaphore.java:26:7:26:11 | state | this field access | examples/FlawedSemaphore.java:26:7:26:11 | state | this expression |
| examples/LockExample.java:24:5:24:10 | length | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:24:5:24:10 | length | this expression | examples/LockExample.java:38:5:38:10 | length | this field access | examples/LockExample.java:38:5:38:10 | length | this expression |
| examples/LockExample.java:24:5:24:10 | length | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:24:5:24:10 | length | this expression | examples/LockExample.java:39:13:39:18 | length | this field access | examples/LockExample.java:39:13:39:18 | length | this expression |
| examples/LockExample.java:24:5:24:10 | length | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:24:5:24:10 | length | this expression | examples/LockExample.java:44:5:44:10 | length | this field access | examples/LockExample.java:44:5:44:10 | length | this expression |
| examples/LockExample.java:24:5:24:10 | length | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:24:5:24:10 | length | this expression | examples/LockExample.java:45:13:45:18 | length | this field access | examples/LockExample.java:45:13:45:18 | length | this expression |
| examples/LockExample.java:24:5:24:10 | length | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:24:5:24:10 | length | this expression | examples/LockExample.java:49:5:49:10 | length | this field access | examples/LockExample.java:49:5:49:10 | length | this expression |
| examples/LockExample.java:24:5:24:10 | length | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:24:5:24:10 | length | this expression | examples/LockExample.java:57:5:57:10 | length | this field access | examples/LockExample.java:57:5:57:10 | length | this expression |
| examples/LockExample.java:24:5:24:10 | length | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:24:5:24:10 | length | this expression | examples/LockExample.java:58:13:58:18 | length | this field access | examples/LockExample.java:58:13:58:18 | length | this expression |
| examples/LockExample.java:24:5:24:10 | length | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:24:5:24:10 | length | this expression | examples/LockExample.java:62:5:62:10 | length | this field access | examples/LockExample.java:62:5:62:10 | length | this expression |
| examples/LockExample.java:24:5:24:10 | length | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:24:5:24:10 | length | this expression | examples/LockExample.java:65:13:65:18 | length | this field access | examples/LockExample.java:65:13:65:18 | length | this expression |
| examples/LockExample.java:24:5:24:10 | length | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:24:5:24:10 | length | this expression | examples/LockExample.java:69:5:69:10 | length | this field access | examples/LockExample.java:69:5:69:10 | length | this expression |
| examples/LockExample.java:24:5:24:10 | length | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:24:5:24:10 | length | this expression | examples/LockExample.java:71:13:71:18 | length | this field access | examples/LockExample.java:71:13:71:18 | length | this expression |
| examples/LockExample.java:24:5:24:10 | length | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:24:5:24:10 | length | this expression | examples/LockExample.java:76:5:76:10 | length | this field access | examples/LockExample.java:76:5:76:10 | length | this expression |
| examples/LockExample.java:24:5:24:10 | length | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:24:5:24:10 | length | this expression | examples/LockExample.java:79:13:79:18 | length | this field access | examples/LockExample.java:79:13:79:18 | length | this expression |
| examples/LockExample.java:24:5:24:10 | length | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:24:5:24:10 | length | this expression | examples/LockExample.java:127:7:127:12 | length | this field access | examples/LockExample.java:127:7:127:12 | length | this expression |
| examples/LockExample.java:24:5:24:10 | length | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:24:5:24:10 | length | this expression | examples/LockExample.java:136:7:136:12 | length | this field access | examples/LockExample.java:136:7:136:12 | length | this expression |
| examples/LockExample.java:24:5:24:10 | length | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:24:5:24:10 | length | this expression | examples/LockExample.java:142:7:142:12 | length | this field access | examples/LockExample.java:142:7:142:12 | length | this expression |
| examples/LockExample.java:25:5:25:11 | content | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:25:5:25:11 | content | this expression | examples/LockExample.java:39:5:39:11 | content | this field access | examples/LockExample.java:39:5:39:11 | content | this expression |
| examples/LockExample.java:25:5:25:11 | content | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:25:5:25:11 | content | this expression | examples/LockExample.java:45:5:45:11 | content | this field access | examples/LockExample.java:45:5:45:11 | content | this expression |
| examples/LockExample.java:25:5:25:11 | content | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:25:5:25:11 | content | this expression | examples/LockExample.java:58:5:58:11 | content | this field access | examples/LockExample.java:58:5:58:11 | content | this expression |
| examples/LockExample.java:25:5:25:11 | content | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:25:5:25:11 | content | this expression | examples/LockExample.java:65:5:65:11 | content | this field access | examples/LockExample.java:65:5:65:11 | content | this expression |
| examples/LockExample.java:25:5:25:11 | content | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:25:5:25:11 | content | this expression | examples/LockExample.java:71:5:71:11 | content | this field access | examples/LockExample.java:71:5:71:11 | content | this expression |
| examples/LockExample.java:25:5:25:11 | content | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:25:5:25:11 | content | this expression | examples/LockExample.java:79:5:79:11 | content | this field access | examples/LockExample.java:79:5:79:11 | content | this expression |
| examples/LockExample.java:38:5:38:10 | length | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:38:5:38:10 | length | this expression | examples/LockExample.java:25:13:25:18 | length | this field access | examples/LockExample.java:25:13:25:18 | length | this expression |
| examples/LockExample.java:38:5:38:10 | length | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:38:5:38:10 | length | this expression | examples/LockExample.java:32:13:32:18 | length | this field access | examples/LockExample.java:32:13:32:18 | length | this expression |
| examples/LockExample.java:38:5:38:10 | length | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:38:5:38:10 | length | this expression | examples/LockExample.java:52:13:52:18 | length | this field access | examples/LockExample.java:52:13:52:18 | length | this expression |
| examples/LockExample.java:38:5:38:10 | length | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:38:5:38:10 | length | this expression | examples/LockExample.java:150:7:150:12 | length | this field access | examples/LockExample.java:150:7:150:12 | length | this expression |
| examples/LockExample.java:39:5:39:11 | content | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:39:5:39:11 | content | this expression | examples/LockExample.java:52:5:52:11 | content | this field access | examples/LockExample.java:52:5:52:11 | content | this expression |
| examples/LockExample.java:85:5:85:21 | notRelatedToOther | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:85:5:85:21 | notRelatedToOther | this expression | examples/LockExample.java:94:5:94:21 | notRelatedToOther | this field access | examples/LockExample.java:94:5:94:21 | notRelatedToOther | this expression |
| examples/LockExample.java:85:5:85:21 | notRelatedToOther | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:85:5:85:21 | notRelatedToOther | this expression | examples/LockExample.java:112:5:112:21 | notRelatedToOther | this field access | examples/LockExample.java:112:5:112:21 | notRelatedToOther | this expression |
| examples/LockExample.java:85:5:85:21 | notRelatedToOther | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:85:5:85:21 | notRelatedToOther | this expression | examples/LockExample.java:119:5:119:21 | notRelatedToOther | this field access | examples/LockExample.java:119:5:119:21 | notRelatedToOther | this expression |
| examples/LockExample.java:85:5:85:21 | notRelatedToOther | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:85:5:85:21 | notRelatedToOther | this expression | examples/LockExample.java:124:5:124:21 | notRelatedToOther | this field access | examples/LockExample.java:124:5:124:21 | notRelatedToOther | this expression |
| examples/LockExample.java:85:5:85:21 | notRelatedToOther | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:85:5:85:21 | notRelatedToOther | this expression | examples/LockExample.java:145:5:145:21 | notRelatedToOther | this field access | examples/LockExample.java:145:5:145:21 | notRelatedToOther | this expression |
| examples/LockExample.java:85:5:85:21 | notRelatedToOther | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:85:5:85:21 | notRelatedToOther | this expression | examples/LockExample.java:153:5:153:21 | notRelatedToOther | this field access | examples/LockExample.java:153:5:153:21 | notRelatedToOther | this expression |
| examples/LockExample.java:94:5:94:21 | notRelatedToOther | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:94:5:94:21 | notRelatedToOther | this expression | examples/LockExample.java:100:5:100:21 | notRelatedToOther | this field access | examples/LockExample.java:100:5:100:21 | notRelatedToOther | this expression |
| examples/LockExample.java:94:5:94:21 | notRelatedToOther | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:94:5:94:21 | notRelatedToOther | this expression | examples/LockExample.java:103:5:103:21 | notRelatedToOther | this field access | examples/LockExample.java:103:5:103:21 | notRelatedToOther | this expression |
| examples/LockExample.java:94:5:94:21 | notRelatedToOther | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:94:5:94:21 | notRelatedToOther | this expression | examples/LockExample.java:109:5:109:21 | notRelatedToOther | this field access | examples/LockExample.java:109:5:109:21 | notRelatedToOther | this expression |
| examples/LockExample.java:94:5:94:21 | notRelatedToOther | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/LockExample.java:94:5:94:21 | notRelatedToOther | this expression | examples/LockExample.java:117:5:117:21 | notRelatedToOther | this field access | examples/LockExample.java:117:5:117:21 | notRelatedToOther | this expression |
| examples/SyncLstExample.java:40:5:40:7 | lst | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/SyncLstExample.java:40:5:40:7 | lst | this expression | examples/SyncLstExample.java:45:5:45:7 | lst | this field access | examples/SyncLstExample.java:45:5:45:7 | lst | this expression |
| examples/SyncStackExample.java:32:5:32:7 | stc | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/SyncStackExample.java:32:5:32:7 | stc | this expression | examples/SyncStackExample.java:37:5:37:7 | stc | this field access | examples/SyncStackExample.java:37:5:37:7 | stc | this expression |
| examples/SynchronizedAndLock.java:14:9:14:14 | length | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/SynchronizedAndLock.java:14:9:14:14 | length | this expression | examples/SynchronizedAndLock.java:19:9:19:14 | length | this field access | examples/SynchronizedAndLock.java:19:9:19:14 | length | this expression |
| examples/Test.java:43:5:43:10 | this.y | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/Test.java:43:5:43:10 | this.y | this expression | examples/Test.java:52:5:52:10 | this.y | this field access | examples/Test.java:24:5:24:18 | setYPrivate(...) | this expression |
| examples/Test.java:43:5:43:10 | this.y | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/Test.java:43:5:43:10 | this.y | this expression | examples/Test.java:60:5:60:10 | this.y | this field access | examples/Test.java:60:5:60:10 | this.y | this expression |
| examples/Test.java:43:5:43:10 | this.y | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/Test.java:43:5:43:10 | this.y | this expression | examples/Test.java:74:5:74:10 | this.y | this field access | examples/Test.java:74:5:74:10 | this.y | this expression |
| examples/Test.java:43:5:43:10 | this.y | This modifying field access (publicly accessible via $@) is conflicting with $@ (publicly accessible via $@) because they are not synchronized with the same monitor. | examples/Test.java:43:5:43:10 | this.y | this expression | examples/Test.java:74:14:74:14 | y | this field access | examples/Test.java:74:14:74:14 | 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: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:18:16:23 | 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:18:16:23 | this.y | this expression |
| examples/C.java:20:9:20: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:20:9:20:14 | this.y | this expression |
| examples/C.java:21:9:21: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:21:9:21:14 | this.y | this expression |
| examples/C.java:22:9:22: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:22:9:22:14 | this.y | this expression |
| examples/C.java:22:18:22:23 | this.y | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/C.java:22:18:22:23 | this.y | this expression |
| examples/C.java:26:9:26: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:26:9:26:14 | this.y | this expression |
| examples/C.java:30:13:30:13 | y | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/C.java:30:13:30:13 | y | this expression |
| examples/C.java:33:9:33:9 | y | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/C.java:33:9:33:9 | y | this expression |
| examples/FaultyTurnstileExample.java:18:5:18:9 | count | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/FaultyTurnstileExample.java:18:5:18:9 | count | this expression |
| examples/FaultyTurnstileExample.java:26:15:26:19 | count | The field $@ is not properly synchronized in that no single monitor covers all accesses, but the class $@ is annotated as @ThreadSafe. | examples/FaultyTurnstileExample.java:23:7:23:29 | FaultyTurnstileExample2 | FaultyTurnstileExample2 |
| examples/FlawedSemaphore.java:15:14:15:18 | state | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/FlawedSemaphore.java:15:14:15:18 | state | this expression |
| examples/FlawedSemaphore.java:18:7:18:11 | state | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/FlawedSemaphore.java:18:7:18:11 | state | this expression |
| examples/LockExample.java:18:15:18:20 | length | The field $@ is not properly synchronized in that no single monitor covers all accesses, but the class $@ is annotated as @ThreadSafe. | examples/LockExample.java:14:14:14:24 | LockExample | LockExample |
| examples/LockExample.java:19:15:19:31 | notRelatedToOther | The field $@ is not properly synchronized in that no single monitor covers all accesses, but the class $@ is annotated as @ThreadSafe. | examples/LockExample.java:14:14:14:24 | LockExample | LockExample |
| examples/LockExample.java:20:17:20:23 | content | The field $@ is not properly synchronized in that no single monitor covers all accesses, but the class $@ is annotated as @ThreadSafe. | examples/LockExample.java:14:14:14:24 | LockExample | LockExample |
| examples/LockExample.java:44:5:44:10 | length | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/LockExample.java:44:5:44:10 | length | this expression |
| examples/LockExample.java:45:5:45:11 | content | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/LockExample.java:45:5:45:11 | content | this expression |
| examples/LockExample.java:45:13:45:18 | length | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/LockExample.java:45:13:45:18 | length | this expression |
| examples/LockExample.java:49:5:49:10 | length | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/LockExample.java:49:5:49:10 | length | this expression |
| examples/LockExample.java:62:5:62:10 | length | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/LockExample.java:62:5:62:10 | length | this expression |
| examples/LockExample.java:65:5:65:11 | content | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/LockExample.java:65:5:65:11 | content | this expression |
| examples/LockExample.java:65:13:65:18 | length | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/LockExample.java:65:13:65:18 | length | this expression |
| examples/LockExample.java:69:5:69:10 | length | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/LockExample.java:69:5:69:10 | length | this expression |
| examples/LockExample.java:71:5:71:11 | content | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/LockExample.java:71:5:71:11 | content | this expression |
| examples/LockExample.java:71:13:71:18 | length | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/LockExample.java:71:13:71:18 | length | this expression |
| examples/LockExample.java:76:5:76:10 | length | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/LockExample.java:76:5:76:10 | length | this expression |
| examples/LockExample.java:79:5:79:11 | content | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/LockExample.java:79:5:79:11 | content | this expression |
| examples/LockExample.java:79:13:79:18 | length | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/LockExample.java:79:13:79:18 | length | this expression |
| examples/LockExample.java:112:5:112:21 | notRelatedToOther | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/LockExample.java:112:5:112:21 | notRelatedToOther | this expression |
| examples/LockExample.java:119:5:119:21 | notRelatedToOther | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/LockExample.java:119:5:119:21 | notRelatedToOther | this expression |
| examples/LockExample.java:124:5:124:21 | notRelatedToOther | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/LockExample.java:124:5:124:21 | notRelatedToOther | this expression |
| examples/LockExample.java:145:5:145:21 | notRelatedToOther | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/LockExample.java:145:5:145:21 | notRelatedToOther | this expression |
| examples/LockExample.java:153:5:153:21 | notRelatedToOther | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/LockExample.java:153:5:153:21 | notRelatedToOther | this expression |
| examples/SyncLstExample.java:45:5:45:7 | lst | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/SyncLstExample.java:45:5:45:7 | lst | this expression |
| examples/SyncStackExample.java:37:5:37:7 | stc | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/SyncStackExample.java:37:5:37:7 | stc | this expression |
| examples/SynchronizedAndLock.java:10:17:10:22 | length | The field $@ is not properly synchronized in that no single monitor covers all accesses, but the class $@ is annotated as @ThreadSafe. | examples/SynchronizedAndLock.java:7:14:7:32 | SynchronizedAndLock | SynchronizedAndLock |
| examples/Test.java:52:5:52:10 | this.y | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/Test.java:24:5:24:18 | setYPrivate(...) | this expression |
| examples/Test.java:60:5:60:10 | this.y | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/Test.java:60:5:60:10 | this.y | this expression |
| examples/Test.java:74:5:74:10 | this.y | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/Test.java:74:5:74:10 | this.y | this expression |
| examples/Test.java:74:14:74:14 | y | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/Test.java:74:14:74:14 | y | this expression |

View File

@@ -12,25 +12,25 @@ public class C {
public void m() {
this.y = 0; // $ Alert
this.y += 1;
this.y = this.y - 1;
this.y += 1; // $ Alert
this.y = this.y - 1; // $ Alert
}
public void n4() {
this.y = 0;
this.y += 1;
this.y = this.y - 1;
this.y = 0; // $ Alert
this.y += 1; // $ Alert
this.y = this.y - 1; // $ Alert
}
public void setY(int y) {
this.y = y;
this.y = y; // $ Alert
}
public void test() {
if (y == 0) {
if (y == 0) { // $ Alert
lock.lock();
}
y = 0;
y = 0; // $ Alert
lock.unlock();
}

View File

@@ -10,12 +10,12 @@ class FaultyTurnstileExample {
public void inc() {
lock.lock();
count++; // $ Alert
count++; // $ MISSING: Alert
lock.unlock();
}
public void dec() {
count--;
count--; // $ Alert
}
}
@@ -23,11 +23,11 @@ class FaultyTurnstileExample {
class FaultyTurnstileExample2 {
private Lock lock1 = new ReentrantLock();
private Lock lock2 = new ReentrantLock();
private int count = 0;
private int count = 0; // $ Alert
public void inc() {
lock1.lock();
count++; // $ Alert
count++;
lock1.unlock();
}

View File

@@ -12,7 +12,7 @@ public class FlawedSemaphore {
public void acquire() {
try {
while (state == capacity) {
while (state == capacity) { // $ Alert
this.wait();
}
state++; // $ Alert

View File

@@ -15,14 +15,14 @@ public class LockExample {
private Lock lock1 = new ReentrantLock();
private Lock lock2 = new ReentrantLock();
private int length = 0;
private int notRelatedToOther = 10;
private int[] content = new int[10];
private int length = 0; // $ Alert
private int notRelatedToOther = 10; // $ Alert
private int[] content = new int[10]; // $ Alert
public void add(int value) {
lock1.lock();
length++; // $ Alert
content[length] = value; // $ Alert
length++;
content[length] = value;
lock1.unlock();
}
@@ -35,18 +35,18 @@ public class LockExample {
public void notTheSameLockAsAdd() { // use locks, but different ones
lock2.lock();
length--; // $ Alert
content[length] = 0; // $ Alert
length--;
content[length] = 0;
lock2.unlock();
}
public void noLock() { // no locks
length--;
content[length] = 0;
length--; // $ Alert
content[length] = 0; // $ Alert
}
public void fieldUpdatedOutsideOfLock() { // adjusts length without lock
length--;
length--; // $ Alert
lock1.lock();
content[length] = 0;
@@ -59,30 +59,30 @@ public class LockExample {
}
public void onlyLocked() { // never unlocked, only locked
length--;
length--; // $ Alert
lock1.lock();
content[length] = 0;
content[length] = 0; // $ Alert
}
public void onlyUnlocked() { // never locked, only unlocked
length--;
length--; // $ Alert
content[length] = 0;
content[length] = 0; // $ Alert
lock1.unlock();
}
public void notSameLock() {
length--;
length--; // $ Alert
lock2.lock();// Not the same lock
content[length] = 0;
content[length] = 0; // $ Alert
lock1.unlock();
}
public void updateCount() {
lock2.lock();
notRelatedToOther++; // $ Alert
notRelatedToOther++;
lock2.unlock();
}
@@ -91,7 +91,7 @@ public class LockExample {
notRelatedToOther++;
lock2.unlock();
lock1.lock();
notRelatedToOther++; // $ Alert
notRelatedToOther++;
lock1.unlock();
}
@@ -109,19 +109,19 @@ public class LockExample {
notRelatedToOther++;
lock2.unlock();
lock1.lock();
notRelatedToOther++;
notRelatedToOther++; // $ Alert
}
public void updateCountTwiceUnLock() {
lock2.lock();
notRelatedToOther++;
lock2.unlock();
notRelatedToOther++;
notRelatedToOther++; // $ Alert
lock1.unlock();
}
public void synchronizedNonRelatedOutside() {
notRelatedToOther++;
notRelatedToOther++; // $ Alert
synchronized(this) {
length++;
@@ -142,7 +142,7 @@ public class LockExample {
length++;
}
notRelatedToOther = 1;
notRelatedToOther = 1; // $ Alert
}
public void synchronizedNonRelatedOutside4() {
@@ -150,7 +150,7 @@ public class LockExample {
length++;
}
notRelatedToOther = 1;
notRelatedToOther = 1; // $ Alert
}
}

View File

@@ -37,11 +37,11 @@ class FaultySyncLstExample<T> {
public void add(T item) {
lock.lock();
lst.add(item); // $ Alert
lst.add(item);
lock.unlock();
}
public void remove(int i) {
lst.remove(i);
lst.remove(i); // $ Alert
}
}

View File

@@ -29,11 +29,11 @@ class FaultySyncStackExample<T> {
public void push(T item) {
lock.lock();
stc.push(item); // $ Alert
stc.push(item);
lock.unlock();
}
public void pop() {
stc.pop();
stc.pop(); // $ Alert
}
}

View File

@@ -7,11 +7,11 @@ import java.util.concurrent.locks.ReentrantLock;
public class SynchronizedAndLock {
private Lock lock = new ReentrantLock();
private int length = 0;
private int length = 0; // $ Alert
public void add(int value) {
lock.lock();
length++; // $ Alert
length++;
lock.unlock();
}

View File

@@ -40,7 +40,7 @@ public class Test {
*/
public void setYCorrect(int y) {
lock.lock();
this.y = y; // $ Alert
this.y = y;
lock.unlock();
}
@@ -49,7 +49,7 @@ public class Test {
* @param y
*/
private void setYPrivate(int y) {
this.y = y;
this.y = y; // $ Alert
}
/**
@@ -57,7 +57,7 @@ public class Test {
* @param y
*/
public void setYWrongLock(int y) {
this.y = y;
this.y = y; // $ Alert
lock.lock();
lock.unlock();
}
@@ -71,6 +71,6 @@ public class Test {
}
public void testMethod() {
this.y = y + 2;
this.y = y + 2; // $ Alert
}
}