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 76129924d1b..b89291d1803 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 @@ -199,6 +199,7 @@ private 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 1d0345e8291..861c673c2e6 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 c3aacf97698..d46ce51964c 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 @@ -1325,6 +1325,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 932d0a5f3c5..4df0d578da3 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 @@ -12,6 +12,7 @@ * @param the type of keys * @param the type of values */ +@SuppressWarnings("resourceleak:required.method.not.known") // Not relevant to resources public class LinkedHashKeyedSet extends AbstractSet implements KeyedSet { /** Produces a key for a value. */ 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 fa28cfbbeaf..3c03083640f 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} 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 6a64df0abb6..713e1bb5e8d 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; @@ -28,10 +29,14 @@ * 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 the abstract store * @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 18d910d0c83..da869dafa19 100644 --- a/checker/src/main/java/org/checkerframework/checker/initialization/InitializationTransfer.java +++ b/checker/src/main/java/org/checkerframework/checker/initialization/InitializationTransfer.java @@ -14,6 +14,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; @@ -59,7 +60,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; 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 9fc8f6745c6..1997f3b7ef1 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/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; 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) {} +}