Skip to content

Commit cf3468c

Browse files
False Positive Potential Resource Leak Warnings - @NotOwning Not Working Correctly (eclipse-jdt#2833)
+ respect an explicit @NotOwning during field analysis + update testSharedField() to show that @NotOwning field is "safe" fixes eclipse-jdt#2635
1 parent 1e41295 commit cf3468c

File tree

2 files changed

+74
-10
lines changed

2 files changed

+74
-10
lines changed

org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/FieldDeclaration.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,13 @@ public FlowInfo analyseCode(MethodScope initializationScope, FlowContext flowCon
111111
&& this.binding != null
112112
&& FakedTrackingVariable.isCloseableNotWhiteListed(this.binding.type))
113113
{
114+
long owningTagBits = this.binding.tagBits & TagBits.AnnotationOwningMASK;
114115
if (this.binding.isStatic()) {
115116
initializationScope.problemReporter().staticResourceField(this);
116-
} else if ((this.binding.tagBits & TagBits.AnnotationOwning) == 0) {
117+
} else if (owningTagBits == 0) {
117118
initializationScope.problemReporter().shouldMarkFieldAsOwning(this);
118-
} else if (!this.binding.declaringClass.hasTypeBit(TypeIds.BitAutoCloseable|TypeIds.BitCloseable)) {
119+
} else if (owningTagBits == TagBits.AnnotationOwning
120+
&& !this.binding.declaringClass.hasTypeBit(TypeIds.BitAutoCloseable|TypeIds.BitCloseable)) {
119121
initializationScope.problemReporter().shouldImplementAutoCloseable(this);
120122
}
121123
}

org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakAnnotatedTests.java

Lines changed: 70 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,7 @@ public class A {
629629
PrintWriter fOther;
630630
@Owning PrintWriter fProper;
631631
boolean useField = false;
632-
A(PrintWriter writer1, PrintWriter writer2, @Owning PrintWriter writer3) {
632+
A(@Owning PrintWriter writer1, PrintWriter writer2, @Owning PrintWriter writer3) {
633633
fWriter = writer1;
634634
fOther = writer2;
635635
fProper = writer3;
@@ -639,21 +639,21 @@ public class A {
639639
},
640640
"""
641641
----------
642-
1. WARNING in A.java (at line 5)
643-
@NotOwning PrintWriter fWriter;
644-
^^^^^^^
645-
It is recommended to mark resource fields as '@Owning' to ensure proper closing
646-
----------
647-
2. WARNING in A.java (at line 6)
642+
1. WARNING in A.java (at line 6)
648643
PrintWriter fOther;
649644
^^^^^^
650645
It is recommended to mark resource fields as '@Owning' to ensure proper closing
651646
----------
652-
3. WARNING in A.java (at line 7)
647+
2. WARNING in A.java (at line 7)
653648
@Owning PrintWriter fProper;
654649
^^^^^^^
655650
Class with resource fields tagged as '@Owning' should implement AutoCloseable
656651
----------
652+
3. ERROR in A.java (at line 9)
653+
A(@Owning PrintWriter writer1, PrintWriter writer2, @Owning PrintWriter writer3) {
654+
^^^^^^^
655+
Resource leak: 'writer1' is never closed
656+
----------
657657
""",
658658
options
659659
);
@@ -1703,4 +1703,66 @@ public class ClassWithStatics {
17031703
""",
17041704
options);
17051705
}
1706+
public void testGH2635() {
1707+
Map<String, String> options = getCompilerOptions();
1708+
options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
1709+
options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
1710+
options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
1711+
runLeakTestWithAnnotations(
1712+
new String[] {
1713+
"owning_test/OwningTest.java",
1714+
"""
1715+
package owning_test;
1716+
1717+
import java.io.FileInputStream;
1718+
import java.io.FileNotFoundException;
1719+
import java.io.IOException;
1720+
import java.io.InputStream;
1721+
1722+
import org.eclipse.jdt.annotation.Owning;
1723+
1724+
public class OwningTest implements AutoCloseable {
1725+
1726+
@Owning
1727+
private InputStream fileInputStream;
1728+
1729+
@SuppressWarnings("unused")
1730+
private NotOwningTest cacheUser;
1731+
1732+
public void initialise() throws FileNotFoundException {
1733+
fileInputStream = new FileInputStream("test.txt");
1734+
cacheUser = new NotOwningTest(fileInputStream);
1735+
}
1736+
1737+
@Override
1738+
public void close() throws IOException {
1739+
fileInputStream.close();
1740+
}
1741+
1742+
}
1743+
""",
1744+
"owning_test/NotOwningTest.java",
1745+
"""
1746+
package owning_test;
1747+
1748+
import java.io.InputStream;
1749+
1750+
import org.eclipse.jdt.annotation.NotOwning;
1751+
1752+
public class NotOwningTest {
1753+
1754+
// If get a warning here - "It is recommended to mark resource fields as '@Owning' to ensure proper closing"
1755+
@NotOwning
1756+
private InputStream cacheInputStream;
1757+
1758+
NotOwningTest(InputStream aCacheInputStream) {
1759+
cacheInputStream = aCacheInputStream;
1760+
}
1761+
1762+
}
1763+
"""
1764+
},
1765+
"",
1766+
options);
1767+
}
17061768
}

0 commit comments

Comments
 (0)