From 137224c06ca07c0f3e0cab6cadc5e3ce51689765 Mon Sep 17 00:00:00 2001 From: Martin Kellogg Date: Thu, 20 Mar 2025 12:23:27 -0400 Subject: [PATCH 1/6] fix 6990 --- .../resourceleak/MustCallConsistencyAnalyzer.java | 6 ++++-- checker/tests/resourceleak/DropOwning.java | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 checker/tests/resourceleak/DropOwning.java diff --git a/checker/src/main/java/org/checkerframework/checker/resourceleak/MustCallConsistencyAnalyzer.java b/checker/src/main/java/org/checkerframework/checker/resourceleak/MustCallConsistencyAnalyzer.java index cee309a4dfc..9fb92c0bd87 100644 --- a/checker/src/main/java/org/checkerframework/checker/resourceleak/MustCallConsistencyAnalyzer.java +++ b/checker/src/main/java/org/checkerframework/checker/resourceleak/MustCallConsistencyAnalyzer.java @@ -353,7 +353,7 @@ public boolean derivedFromMustCallAlias() { } /** - * Gets the must-call type associated with the given resource alias, falling on back on the + * Gets the must-call type associated with the given resource alias, falling back on the * declared type if there is no refined type for the alias in the store. * * @param alias a resource alias @@ -367,7 +367,9 @@ private static AnnotationMirror getMustCallValue( CFValue value = mcStore == null ? null : mcStore.getValue(reference); if (value != null) { AnnotationMirror result = - AnnotationUtils.getAnnotationByClass(value.getAnnotations(), MustCall.class); + mcAtf + .getQualifierHierarchy() + .findAnnotationInHierarchy(value.getAnnotations(), mcAtf.TOP); if (result != null) { return result; } diff --git a/checker/tests/resourceleak/DropOwning.java b/checker/tests/resourceleak/DropOwning.java new file mode 100644 index 00000000000..219dfd93efe --- /dev/null +++ b/checker/tests/resourceleak/DropOwning.java @@ -0,0 +1,15 @@ +// test case for https://github.com/typetools/checker-framework/issues/6990 + +import java.io.Closeable; +import org.checkerframework.checker.mustcall.qual.MustCallUnknown; +import org.checkerframework.checker.mustcall.qual.Owning; + +public class DropOwning { + + public void f(@Owning Closeable resource) { + drop(resource); + } + + // :: error: required.method.not.known + private void drop(@Owning @MustCallUnknown Object resourceCF6990) {} +} From 32e26b5c7e4b125d2ca2a9b5fc71046df45b4ab0 Mon Sep 17 00:00:00 2001 From: Martin Kellogg Date: Mon, 24 Mar 2025 14:34:19 -0400 Subject: [PATCH 2/6] ignore excess warning on crash test --- .../tests/ainfer-resourceleak/non-annotated/CrashForTempVar.java | 1 + 1 file changed, 1 insertion(+) diff --git a/checker/tests/ainfer-resourceleak/non-annotated/CrashForTempVar.java b/checker/tests/ainfer-resourceleak/non-annotated/CrashForTempVar.java index ed72d1603f2..edc40f68360 100644 --- a/checker/tests/ainfer-resourceleak/non-annotated/CrashForTempVar.java +++ b/checker/tests/ainfer-resourceleak/non-annotated/CrashForTempVar.java @@ -2,6 +2,7 @@ * Demonstrates an issue in the Checker Framework with handling the nearest enclosing element for * temporary variable declarations, leading to a crash during analysis. */ +@SuppressWarnings("all") // only check for crashes public abstract class CrashForTempVar { private final CrashForTempVar _base; From aae6acd81053a4890d11f606922e336e64817b3d Mon Sep 17 00:00:00 2001 From: Martin Kellogg Date: Mon, 24 Mar 2025 14:56:59 -0400 Subject: [PATCH 3/6] annotations to remove false positives --- .../checker/initialization/InitializationStore.java | 7 +++++-- .../checker/initialization/InitializationTransfer.java | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/checker/src/main/java/org/checkerframework/checker/initialization/InitializationStore.java b/checker/src/main/java/org/checkerframework/checker/initialization/InitializationStore.java index 565d8b3cbfe..22367c6d520 100644 --- a/checker/src/main/java/org/checkerframework/checker/initialization/InitializationStore.java +++ b/checker/src/main/java/org/checkerframework/checker/initialization/InitializationStore.java @@ -8,6 +8,7 @@ import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.Element; import javax.lang.model.element.VariableElement; +import org.checkerframework.checker.mustcall.qual.MustCall; import org.checkerframework.dataflow.cfg.node.MethodInvocationNode; import org.checkerframework.dataflow.cfg.visualize.CFGVisualizer; import org.checkerframework.dataflow.expression.ClassName; @@ -30,8 +31,10 @@ * * @see InitializationTransfer */ -public class InitializationStore, S extends InitializationStore> - extends CFAbstractStore { +public class InitializationStore< + V extends CFAbstractValue<@MustCall({}) V>, + S extends InitializationStore<@MustCall({}) V, @MustCall({}) S>> + extends CFAbstractStore<@MustCall({}) V, @MustCall({}) S> { /** The set of fields that are initialized. */ protected final Set initializedFields; diff --git a/checker/src/main/java/org/checkerframework/checker/initialization/InitializationTransfer.java b/checker/src/main/java/org/checkerframework/checker/initialization/InitializationTransfer.java index e3db178e1ca..3ea55b85657 100644 --- a/checker/src/main/java/org/checkerframework/checker/initialization/InitializationTransfer.java +++ b/checker/src/main/java/org/checkerframework/checker/initialization/InitializationTransfer.java @@ -13,6 +13,7 @@ import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.ElementFilter; +import org.checkerframework.checker.mustcall.qual.MustCall; import org.checkerframework.dataflow.analysis.RegularTransferResult; import org.checkerframework.dataflow.analysis.TransferInput; import org.checkerframework.dataflow.analysis.TransferResult; @@ -56,7 +57,7 @@ public class InitializationTransfer< V extends CFAbstractValue, T extends InitializationTransfer, - S extends InitializationStore> + S extends InitializationStore<@MustCall({}) V, @MustCall({}) S>> extends CFAbstractTransfer { protected final InitializationAnnotatedTypeFactory atypeFactory; From 0a8b1b9f0b319571e38377ee7585f233f2fe6d51 Mon Sep 17 00:00:00 2001 From: Michael Ernst Date: Tue, 25 Mar 2025 16:00:52 -0700 Subject: [PATCH 4/6] Add Javadoc --- .../checker/initialization/InitializationStore.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/checker/src/main/java/org/checkerframework/checker/initialization/InitializationStore.java b/checker/src/main/java/org/checkerframework/checker/initialization/InitializationStore.java index 22367c6d520..3fc2b9435c7 100644 --- a/checker/src/main/java/org/checkerframework/checker/initialization/InitializationStore.java +++ b/checker/src/main/java/org/checkerframework/checker/initialization/InitializationStore.java @@ -29,6 +29,8 @@ * A store that extends {@code CFAbstractStore} and additionally tracks which fields of the 'self' * reference have been initialized. * + * @param the type of values in the abstract store + * @param the type of teh abstract store * @see InitializationTransfer */ public class InitializationStore< From c6e6d94371a81dcf436dc880ec11a04a2baafe52 Mon Sep 17 00:00:00 2001 From: Martin Kellogg Date: Fri, 18 Jul 2025 11:00:29 -0400 Subject: [PATCH 5/6] Update checker/src/main/java/org/checkerframework/checker/initialization/InitializationStore.java Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../checker/initialization/InitializationStore.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/checker/src/main/java/org/checkerframework/checker/initialization/InitializationStore.java b/checker/src/main/java/org/checkerframework/checker/initialization/InitializationStore.java index 3fc2b9435c7..95a0eea86bd 100644 --- a/checker/src/main/java/org/checkerframework/checker/initialization/InitializationStore.java +++ b/checker/src/main/java/org/checkerframework/checker/initialization/InitializationStore.java @@ -30,7 +30,7 @@ * reference have been initialized. * * @param the type of values in the abstract store - * @param the type of teh abstract store + * @param the type of the abstract store * @see InitializationTransfer */ public class InitializationStore< From 0b0d74f3f26c9dd1d7d1b24fdf1eab185975a483 Mon Sep 17 00:00:00 2001 From: Martin Kellogg Date: Thu, 24 Jul 2025 13:41:18 -0400 Subject: [PATCH 6/6] add suppressions and annotations to AFU --- .../src/main/java/org/checkerframework/afu/annotator/Main.java | 1 + .../org/checkerframework/afu/scenelib/el/TypeASTMapper.java | 1 + .../java/org/checkerframework/afu/scenelib/io/ASTPath.java | 1 + .../java/org/checkerframework/afu/scenelib/util/SceneOps.java | 1 + .../afu/scenelib/util/coll/LinkedHashKeyedSet.java | 1 + .../checkerframework/afu/scenelib/util/coll/VivifyingMap.java | 3 ++- 6 files changed, 7 insertions(+), 1 deletion(-) diff --git a/annotation-file-utilities/src/main/java/org/checkerframework/afu/annotator/Main.java b/annotation-file-utilities/src/main/java/org/checkerframework/afu/annotator/Main.java index 833b2a9e57e..fc06d629593 100644 --- a/annotation-file-utilities/src/main/java/org/checkerframework/afu/annotator/Main.java +++ b/annotation-file-utilities/src/main/java/org/checkerframework/afu/annotator/Main.java @@ -195,6 +195,7 @@ public class Main { // TODO: remove this. public static boolean temporaryDebug = false; + @SuppressWarnings("resourceleak:required.method.not.known") // Not relevant to resources private static ElementVisitor classFilter = new ElementVisitor() { Void filter(VivifyingMap vm0, VivifyingMap vm1) { diff --git a/annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/el/TypeASTMapper.java b/annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/el/TypeASTMapper.java index 8da0bc1e901..c952a33b475 100644 --- a/annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/el/TypeASTMapper.java +++ b/annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/el/TypeASTMapper.java @@ -22,6 +22,7 @@ * * @param common supertype of the AST nodes */ +@SuppressWarnings("resourceleak:required.method.not.known") // Not relevant to resources public abstract class TypeASTMapper { /** Constructs a {@link TypeASTMapper}. A {@link TypeASTMapper} stores no state. */ protected TypeASTMapper() {} diff --git a/annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/io/ASTPath.java b/annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/io/ASTPath.java index b2e1536a0c1..5a66a26d9f9 100644 --- a/annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/io/ASTPath.java +++ b/annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/io/ASTPath.java @@ -1433,6 +1433,7 @@ public String toString() { * * @param type of stack elements */ +@SuppressWarnings("resourceleak:required.method.not.known") // Not relevant to resources class ImmutableStack { // The stack is implemented as a linked list: diff --git a/annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/util/SceneOps.java b/annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/util/SceneOps.java index 0d27057d449..3e2f9674896 100644 --- a/annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/util/SceneOps.java +++ b/annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/util/SceneOps.java @@ -289,6 +289,7 @@ public Void visitElement(AElement minuend, Pair eltPair) { * Calculates difference between {@code minuend} and first component of {@code eltPair}, adding * results to second component of {@code eltPair}. */ + @SuppressWarnings("resourceleak:required.method.not.known") // Not relevant to resources private void visitElements( VivifyingMap minuend, VivifyingMap subtrahend, VivifyingMap difference) { if (minuend != null) { diff --git a/annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/util/coll/LinkedHashKeyedSet.java b/annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/util/coll/LinkedHashKeyedSet.java index f20dd9d0859..b723361f1b6 100644 --- a/annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/util/coll/LinkedHashKeyedSet.java +++ b/annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/util/coll/LinkedHashKeyedSet.java @@ -10,6 +10,7 @@ * A simple implementation of {@link KeyedSet} backed by an insertion-order {@link * java.util.LinkedHashMap} and its {@link java.util.LinkedHashMap#values() value collection}. */ +@SuppressWarnings("resourceleak:required.method.not.known") // Not relevant to resources public class LinkedHashKeyedSet extends AbstractSet implements KeyedSet { private final Keyer keyer; diff --git a/annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/util/coll/VivifyingMap.java b/annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/util/coll/VivifyingMap.java index d3e06819bc1..27e40a2dd67 100644 --- a/annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/util/coll/VivifyingMap.java +++ b/annotation-file-utilities/src/main/java/org/checkerframework/afu/scenelib/util/coll/VivifyingMap.java @@ -2,6 +2,7 @@ import java.util.Iterator; import java.util.Map; +import org.checkerframework.checker.mustcall.qual.MustCall; /** * A {@link VivifyingMap} is a map with two additional methods: @@ -12,7 +13,7 @@ *
  • {@link #prune} removes empty values * */ -public abstract class VivifyingMap extends WrapperMap { +public abstract class VivifyingMap extends WrapperMap { /** * Constructs a new {@link VivifyingMap} backed by the given map. All reads and writes to this * {@link VivifyingMap} go through to the backing map. However, since the {@link VivifyingMap}