diff --git a/java/ql/lib/semmle/code/java/ConflictingAccess.qll b/java/ql/lib/semmle/code/java/ConflictingAccess.qll index ceff3e4ffa3..12886769095 100644 --- a/java/ql/lib/semmle/code/java/ConflictingAccess.qll +++ b/java/ql/lib/semmle/code/java/ConflictingAccess.qll @@ -63,12 +63,23 @@ class ExposedField extends Field { not this.getType() instanceof LockType and // field is not thread-safe not isThreadSafeType(this.getType()) and - not isThreadSafeType(this.getInitializer().getType()) and + not isThreadSafeType(initialValue(this).getType()) and // the initializer guarantees thread safety - not isThreadSafeInitializer(this.getInitializer()) + not isThreadSafeInitializer(initialValue(this)) } } +/** + * Gets the initial value for the field `f`. + * This is either a static initializer or an assignment in a constructor. + */ +Expr initialValue(Field f) { + result = f.getInitializer() + or + result = f.getAnAssignedValue() and + result.getEnclosingCallable() = f.getDeclaringType().getAConstructor() +} + /** * A field access that is exposed to potential data races. * We require the field to be in a class that is annotated as `@ThreadSafe`. diff --git a/java/ql/test/query-tests/ThreadSafe/ThreadSafe.expected b/java/ql/test/query-tests/ThreadSafe/ThreadSafe.expected index c0df4852d78..488cfa1a482 100644 --- a/java/ql/test/query-tests/ThreadSafe/ThreadSafe.expected +++ b/java/ql/test/query-tests/ThreadSafe/ThreadSafe.expected @@ -43,7 +43,4 @@ | 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 | -| examples/ThreadSafeInitializers.java:29:9:29:16 | sync_map | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/ThreadSafeInitializers.java:29:9:29:16 | sync_map | this expression | -| examples/ThreadSafeInitializers.java:37:9:37:12 | cmap | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/ThreadSafeInitializers.java:37:9:37:12 | cmap | this expression | | examples/ThreadSafeInitializers.java:45:9:45:14 | this.y | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/ThreadSafeInitializers.java:45:9:45:14 | this.y | this expression | -| examples/ThreadSafeInitializers.java:49:9:49:11 | set | This field access (publicly accessible via $@) is not protected by any monitor, but the class is annotated as @ThreadSafe. | examples/ThreadSafeInitializers.java:49:9:49:11 | set | this expression | diff --git a/java/ql/test/query-tests/ThreadSafe/examples/ThreadSafeInitializers.java b/java/ql/test/query-tests/ThreadSafe/examples/ThreadSafeInitializers.java index 8262c6bf69e..b8f50405066 100644 --- a/java/ql/test/query-tests/ThreadSafe/examples/ThreadSafeInitializers.java +++ b/java/ql/test/query-tests/ThreadSafe/examples/ThreadSafeInitializers.java @@ -26,7 +26,7 @@ public class ThreadSafeInitializers { } public void sync_map_put(Integer i, Integer v) { - sync_map.put(i,v); // $ SPURIOUS: Alert + sync_map.put(i,v); } public void sync_map_initialised_put(Integer i, Integer v) { @@ -34,7 +34,7 @@ public class ThreadSafeInitializers { } public void cmap_put(String s1, String s2) { - cmap.put(s1, s2); // $ SPURIOUS: Alert + cmap.put(s1, s2); } public void cmap_initialised_put(String s1, String s2) { @@ -46,7 +46,7 @@ public class ThreadSafeInitializers { } public void set_add(Integer i) { - set.add(i); // $ SPURIOUS: Alert + set.add(i); } public void set_initialised_add(Integer i) {