typetools / typetools/checker-framework
Resource Leak Checker: false positives when a resource is allocated and closed in the same expression
Open
@kelloggm is already working on this.
Since Dec 14, 2023.
ResourceLeakChecker
- Dominant language
- Java
- Stars
- 1.1k
- Forks
- 440
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 134
Description
The Resource Leak Checker does not accept this code:
static void method() {
// error: [required.method.not.called] @MustCall method close may not have been invoked on new Resource()
close(new Resource());
}
@EnsuresCalledMethods(value = "#1", methods = "close")
static void close(Resource r) {
r.close();
}
this very similar code works:
static void method() {
Resource r = new Resource();
close(r);
}
However, that refactoring is not possible when
methodis a constructorcloseis a call tosuper(...)orthis(...)
For example:
class TestCase {
@EnsuresCalledMethods(value = "#1", methods = "close")
TestCase(Resource r) {
r.close();
}
TestCase() {
// error: [required.method.not.called] @MustCall method close may not have been invoked on new Resource()
this(new Resource());
}
}
Below is a more complete set of tests that exercise a few variants of that pattern. The RLC reports false positives for test cases 3-7.
import java.io.*;
import org.checkerframework.checker.calledmethods.qual.*;
class AllocResourceInExpression {
static void testCase1() {
new Resource().close();
}
static void testCase2() {
alloc().close();
}
static void testCase3() {
new Resource().free();
}
static void testCase4() {
alloc().free();
}
static void testCase5() {
close(new Resource());
}
static void testCase6() {
close(alloc());
}
class TestCase7 {
@EnsuresCalledMethods(value = "#1", methods = "close")
TestCase7(Resource r) {
r.close();
}
TestCase7() {
this(new Resource());
}
}
static class Resource implements Closeable {
@Override
public void close() {}
@EnsuresCalledMethods(value = "this", methods = "close")
public void free() {
close();
}
}
static Resource alloc() {
return new Resource();
}
@EnsuresCalledMethods(value = "#1", methods = "close")
static void close(Resource r) {
r.close();
}
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.