Skip to content

Commit 17b4276

Browse files
committed
Java: Fix bug in qltest and query for immutable types.
1 parent 944c082 commit 17b4276

File tree

5 files changed

+33
-13
lines changed

5 files changed

+33
-13
lines changed

java/ql/src/Likely Bugs/Concurrency/DoubleCheckedLocking.ql

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,19 @@ import DoubleCheckedLocking
1717

1818
predicate allFieldsFinal(Class c) { forex(Field f | c.inherits(f) | f.isFinal()) }
1919

20+
predicate immutableFieldType(Type t) {
21+
allFieldsFinal(t) or
22+
t instanceof ImmutableType
23+
}
24+
2025
from IfStmt if1, IfStmt if2, SynchronizedStmt sync, Field f
2126
where
2227
doubleCheckedLocking(if1, if2, sync, f) and
2328
not f.isVolatile() and
2429
not (
2530
// Non-volatile double-checked locking is ok when the object is immutable and
2631
// there is only a single non-synchronized field read.
27-
allFieldsFinal(f.getType()) and
32+
immutableFieldType(f.getType()) and
2833
1 = strictcount(FieldAccess fa |
2934
fa.getField() = f and
3035
fa.getEnclosingCallable() = sync.getEnclosingCallable() and

java/ql/src/Likely Bugs/Concurrency/DoubleCheckedLocking.qll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,5 @@ predicate doubleCheckedLocking(IfStmt if1, IfStmt if2, SynchronizedStmt sync, Fi
3838
if1.getThen() = sync.getParent*() and
3939
sync.getBlock() = if2.getParent*() and
4040
if1.getCondition() = getANullCheck(f) and
41-
if2.getCondition() = getANullCheck(f) and
42-
not f.getType() instanceof ImmutableType
41+
if2.getCondition() = getANullCheck(f)
4342
}

java/ql/test/query-tests/DoubleCheckedLocking/A.java

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,31 @@ public void setX(int x) {
66
}
77
}
88

9-
private String s;
10-
public String getString() {
11-
if (s == null) {
9+
private String s1;
10+
public String getString1() {
11+
if (s1 == null) {
1212
synchronized(this) {
13-
if (s == null) {
14-
s = "string"; // OK, immutable
13+
if (s1 == null) {
14+
s1 = "string"; // BAD, immutable but read twice outside sync
1515
}
1616
}
1717
}
18-
return s;
18+
return s1;
19+
}
20+
21+
private String s2;
22+
public String getString2() {
23+
String x = s2;
24+
if (x == null) {
25+
synchronized(this) {
26+
x = s2;
27+
if (x == null) {
28+
x = "string"; // OK, immutable and read once outside sync
29+
s2 = x;
30+
}
31+
}
32+
}
33+
return x;
1934
}
2035

2136
private B b1;
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
| A.java:25:7:30:7 | stmt | Double-checked locking on the non-volatile field $@ is not thread-safe. | A.java:21:13:21:14 | b1 | b1 |
2-
| A.java:86:7:91:7 | stmt | Double-checked locking on the non-volatile field $@ is not thread-safe. | A.java:83:26:83:27 | b5 | b5 |
1+
| A.java:12:7:16:7 | stmt | Double-checked locking on the non-volatile field $@ is not thread-safe. | A.java:9:18:9:19 | s1 | s1 |
2+
| A.java:40:7:45:7 | stmt | Double-checked locking on the non-volatile field $@ is not thread-safe. | A.java:36:13:36:14 | b1 | b1 |
3+
| A.java:101:7:106:7 | stmt | Double-checked locking on the non-volatile field $@ is not thread-safe. | A.java:98:26:98:27 | b5 | b5 |
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
| A.java:55:11:55:22 | ...=... | Potential race condition. This assignment to $@ is visible to other threads before the subsequent statements are executed. | A.java:50:22:50:23 | b3 | b3 |
2-
| A.java:68:11:68:22 | ...=... | Potential race condition. This assignment to $@ is visible to other threads before the subsequent statements are executed. | A.java:63:22:63:23 | b4 | b4 |
1+
| A.java:70:11:70:22 | ...=... | Potential race condition. This assignment to $@ is visible to other threads before the subsequent statements are executed. | A.java:65:22:65:23 | b3 | b3 |
2+
| A.java:83:11:83:22 | ...=... | Potential race condition. This assignment to $@ is visible to other threads before the subsequent statements are executed. | A.java:78:22:78:23 | b4 | b4 |

0 commit comments

Comments
 (0)