Skip to content

Commit

Permalink
ecj: Duplicate resource leak warnings (eclipse-jdt#2380)
Browse files Browse the repository at this point in the history
fixes eclipse-jdt#1867

Detect the leak already when analyzing the MessageSend whose receiver is
the leaking expression.
  • Loading branch information
stephan-herrmann authored Apr 23, 2024
1 parent 279fc9d commit 167aa96
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ public static FlowInfo analyseCloseableAcquisition(BlockScope scope, FlowInfo fl
}
}

private static boolean isFluentMethod(MethodBinding binding) {
static boolean isFluentMethod(MethodBinding binding) {
if (binding.isStatic())
return false;
ReferenceBinding declaringClass = binding.declaringClass;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,12 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl
// NullReferenceTest#test0510
}
// after having analysed exceptions above start tracking newly allocated resource:
if (analyseResources && FakedTrackingVariable.isAnyCloseable(this.resolvedType))
flowInfo = FakedTrackingVariable.analyseCloseableAcquisition(currentScope, flowInfo, flowContext, this);
if (analyseResources) {
if (FakedTrackingVariable.isAnyCloseable(this.resolvedType))
flowInfo = FakedTrackingVariable.analyseCloseableAcquisition(currentScope, flowInfo, flowContext, this);
if (!FakedTrackingVariable.isFluentMethod(this.binding))
FakedTrackingVariable.cleanUpUnassigned(currentScope, this.receiver, flowInfo, false);
}

manageSyntheticAccessIfNecessary(currentScope, flowInfo);
// account for pot. exceptions thrown by method execution
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7135,6 +7135,67 @@ void test(int sw) {
"----------\n",
options);
}
public void testGH1867_dupes() {
if (this.complianceLevel < ClassFileConstants.JDK1_8) // uses lambda
return;
Map options = getCompilerOptions();
options.put(CompilerOptions.OPTION_ReportPotentiallyUnclosedCloseable, CompilerOptions.ERROR);
options.put(CompilerOptions.OPTION_ReportUnclosedCloseable, CompilerOptions.ERROR);
options.put(CompilerOptions.OPTION_ReportExplicitlyClosedAutoCloseable, CompilerOptions.ERROR);
runLeakTest(
new String[] {
"GH1867.java",
"""
import java.io.IOException;
import java.nio.file.*;
import java.util.Map;
class CtSym {
public CtSym(Path x) throws IOException { }
public FileSystem getFs() {
return null;
}
}
class RuntimeIOException extends RuntimeException {
private static final long serialVersionUID = 1L;
public RuntimeIOException(IOException cause) {
super(cause);
}
@Override
public synchronized IOException getCause() {
return (IOException) super.getCause();
}
}
public class GH1867 {
public static CtSym getCtSym(Path jdkHome, Map<Path, CtSym> ctSymFiles) throws IOException {
CtSym ctSym;
try {
ctSym = ctSymFiles.compute(jdkHome, (Path x, CtSym current) -> {
if (current == null || !current.getFs().isOpen()) {
try {
return new CtSym(x);
} catch (IOException e) {
throw new RuntimeIOException(e);
}
}
return current;
});
} catch (RuntimeIOException rio) {
throw rio.getCause();
}
return ctSym;
}
}
"""
},
"----------\n" +
"1. ERROR in GH1867.java (at line 26)\n" +
" if (current == null || !current.getFs().isOpen()) {\n" +
" ^^^^^^^^^^^^^^^\n" +
potentialOrDefiniteLeak("<unassigned Closeable value>") +
"----------\n",
options);
}
public void testGH2207_1() {
if (this.complianceLevel < ClassFileConstants.JDK1_8)
return;
Expand Down

0 comments on commit 167aa96

Please sign in to comment.