From a65d385297d3a58043f38b20ba13fb0de1610581 Mon Sep 17 00:00:00 2001 From: yoff Date: Tue, 25 Nov 2025 15:42:07 +0100 Subject: [PATCH] java: add tests for thread safe initialisation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Raúl Pardo --- .../ThreadSafe/ThreadSafe.expected | 4 ++ .../examples/ThreadSafeInitializers.java | 55 +++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 java/ql/test/query-tests/ThreadSafe/examples/ThreadSafeInitializers.java diff --git a/java/ql/test/query-tests/ThreadSafe/ThreadSafe.expected b/java/ql/test/query-tests/ThreadSafe/ThreadSafe.expected index 3d73caaffe5..c0df4852d78 100644 --- a/java/ql/test/query-tests/ThreadSafe/ThreadSafe.expected +++ b/java/ql/test/query-tests/ThreadSafe/ThreadSafe.expected @@ -43,3 +43,7 @@ | 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 new file mode 100644 index 00000000000..8262c6bf69e --- /dev/null +++ b/java/ql/test/query-tests/ThreadSafe/examples/ThreadSafeInitializers.java @@ -0,0 +1,55 @@ +package examples; + +import java.util.Map; +import java.util.Set; +import java.util.HashMap; +import java.util.Collections; +import java.util.concurrent.ConcurrentHashMap; + +@ThreadSafe +public class ThreadSafeInitializers { + + private int y; + private final Map sync_map; + private final Map sync_map_initialised = Collections.synchronizedMap(new HashMap()); + + + private final Map cmap; + private final Map cmap_initialised = new ConcurrentHashMap(); + private final Set set; + private final Set set_initialised = ConcurrentHashMap.newKeySet(); + + public ThreadSafeInitializers() { + sync_map = Collections.synchronizedMap(new HashMap()); + cmap = new ConcurrentHashMap(); + set = ConcurrentHashMap.newKeySet(); + } + + public void sync_map_put(Integer i, Integer v) { + sync_map.put(i,v); // $ SPURIOUS: Alert + } + + public void sync_map_initialised_put(Integer i, Integer v) { + sync_map_initialised.put(i,v); + } + + public void cmap_put(String s1, String s2) { + cmap.put(s1, s2); // $ SPURIOUS: Alert + } + + public void cmap_initialised_put(String s1, String s2) { + cmap_initialised.put(s1, s2); + } + + public void setY(int y) { + this.y = y; // $ Alert + } + + public void set_add(Integer i) { + set.add(i); // $ SPURIOUS: Alert + } + + public void set_initialised_add(Integer i) { + set_initialised.add(i); + } +} \ No newline at end of file