View | Details | Raw Unified | Return to bug 358903 | Differences between
and this patch

Collapse All | Expand All

(-)a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java (-15 / +15 lines)
Lines 2702-2722 public void test063a() throws IOException { Link Here
2702
			"    }\n" +
2702
			"    }\n" +
2703
			"}\n"
2703
			"}\n"
2704
		},
2704
		},
2705
		"----------\n" +
2705
		"----------\n" + 
2706
		"1. ERROR in X.java (at line 8)\n" +
2706
		"1. ERROR in X.java (at line 7)\n" + 
2707
		"	BufferedInputStream bis = new BufferedInputStream(stream); // never since reassigned\n" +
2707
		"	FileInputStream stream = new FileInputStream(file);\n" + 
2708
		"	                    ^^^\n" +
2708
		"	                ^^^^^^\n" + 
2709
		"Resource leak: \'bis\' is never closed\n" +
2709
		"Resource leak: \'stream\' is never closed\n" + 
2710
		"----------\n" +
2710
		"----------\n" + 
2711
		"2. ERROR in X.java (at line 9)\n" +
2711
		"2. ERROR in X.java (at line 9)\n" + 
2712
		"	FileInputStream stream2 = new FileInputStream(file); // unsure since passed to method\n" +
2712
		"	FileInputStream stream2 = new FileInputStream(file); // unsure since passed to method\n" + 
2713
		"	                ^^^^^^^\n" +
2713
		"	                ^^^^^^^\n" + 
2714
		"Potential resource leak: \'stream2\' may not be closed\n" +
2714
		"Potential resource leak: \'stream2\' may not be closed\n" + 
2715
		"----------\n" +
2715
		"----------\n" + 
2716
		"3. ERROR in X.java (at line 10)\n" +
2716
		"3. ERROR in X.java (at line 10)\n" + 
2717
		"	bis = getReader(stream2); // unsure since obtained from method\n" +
2717
		"	bis = getReader(stream2); // unsure since obtained from method\n" + 
2718
		"	^^^^^^^^^^^^^^^^^^^^^^^^\n" +
2718
		"	^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
2719
		"Potential resource leak: \'bis\' may not be closed\n" +
2719
		"Potential resource leak: \'bis\' may not be closed\n" + 
2720
		"----------\n",
2720
		"----------\n",
2721
		null,
2721
		null,
2722
		true,
2722
		true,
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java (-1 / +1 lines)
Lines 64-70 public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl Link Here
64
		.unconditionalInits();
64
		.unconditionalInits();
65
65
66
	if (shouldAnalyseResource)
66
	if (shouldAnalyseResource)
67
		FakedTrackingVariable.handleResourceAssignment(preInitInfo, flowInfo, this, this.expression, local);
67
		FakedTrackingVariable.handleResourceAssignment(currentScope, preInitInfo, flowInfo, this, this.expression, local);
68
	else
68
	else
69
		FakedTrackingVariable.cleanUpAfterAssignment(currentScope, this.lhs.bits, this.expression);
69
		FakedTrackingVariable.cleanUpAfterAssignment(currentScope, this.lhs.bits, this.expression);
70
70
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java (-4 / +10 lines)
Lines 284-289 public class FakedTrackingVariable extends LocalDeclaration { Link Here
284
	/** 
284
	/** 
285
	 * Check if the rhs of an assignment or local declaration is an (Auto)Closeable.
285
	 * Check if the rhs of an assignment or local declaration is an (Auto)Closeable.
286
	 * If so create or re-use a tracking variable, and wire and initialize everything.
286
	 * If so create or re-use a tracking variable, and wire and initialize everything.
287
	 * @param scope scope containing the assignment
287
	 * @param upstreamInfo info without analysis of the rhs, use this to determine the status of a resource being disconnected
288
	 * @param upstreamInfo info without analysis of the rhs, use this to determine the status of a resource being disconnected
288
	 * @param flowInfo info with analysis of the rhs, use this for recording resource status because this will be passed downstream
289
	 * @param flowInfo info with analysis of the rhs, use this for recording resource status because this will be passed downstream
289
	 * @param location where to report warnigs/errors against
290
	 * @param location where to report warnigs/errors against
Lines 291-297 public class FakedTrackingVariable extends LocalDeclaration { Link Here
291
	 *			The caller has already checked that the rhs is either of a closeable type or null.
292
	 *			The caller has already checked that the rhs is either of a closeable type or null.
292
	 * @param local the local variable into which the rhs is being assigned
293
	 * @param local the local variable into which the rhs is being assigned
293
	 */
294
	 */
294
	public static void handleResourceAssignment(FlowInfo upstreamInfo, FlowInfo flowInfo, ASTNode location, Expression rhs, LocalVariableBinding local)
295
	public static void handleResourceAssignment(BlockScope scope, FlowInfo upstreamInfo, FlowInfo flowInfo, ASTNode location, Expression rhs, LocalVariableBinding local)
295
	{
296
	{
296
		// does the LHS (local) already have a tracker, indicating we may leak a resource by the assignment?
297
		// does the LHS (local) already have a tracker, indicating we may leak a resource by the assignment?
297
		FakedTrackingVariable previousTracker = null;
298
		FakedTrackingVariable previousTracker = null;
Lines 338-346 public class FakedTrackingVariable extends LocalDeclaration { Link Here
338
		}
339
		}
339
340
340
		if (disconnectedTracker != null) {
341
		if (disconnectedTracker != null) {
341
			int upstreamStatus = upstreamInfo.nullStatus(disconnectedTracker.binding);
342
			if (disconnectedTracker.innerTracker != null && disconnectedTracker.innerTracker.binding.declaringScope == scope) {
342
			if (upstreamStatus != FlowInfo.NON_NULL)
343
				disconnectedTracker.innerTracker.outerTracker = null;
343
				disconnectedTracker.recordErrorLocation(location, upstreamStatus);
344
				scope.pruneWrapperTrackingVar(disconnectedTracker);
345
			} else {
346
				int upstreamStatus = upstreamInfo.nullStatus(disconnectedTracker.binding);
347
				if (upstreamStatus != FlowInfo.NON_NULL)
348
					disconnectedTracker.recordErrorLocation(location, upstreamStatus);
349
			}
344
		}
350
		}
345
	}
351
	}
346
	/**
352
	/**
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java (-1 / +1 lines)
Lines 91-97 public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl Link Here
91
			.unconditionalInits();
91
			.unconditionalInits();
92
92
93
	if (shouldAnalyseResource)
93
	if (shouldAnalyseResource)
94
		FakedTrackingVariable.handleResourceAssignment(preInitInfo, flowInfo, this, this.initialization, this.binding);
94
		FakedTrackingVariable.handleResourceAssignment(currentScope, preInitInfo, flowInfo, this, this.initialization, this.binding);
95
	else
95
	else
96
		FakedTrackingVariable.cleanUpAfterAssignment(currentScope, Binding.LOCAL, this.initialization);
96
		FakedTrackingVariable.cleanUpAfterAssignment(currentScope, Binding.LOCAL, this.initialization);
97
97
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java (+4 lines)
Lines 993-998 public void removeTrackingVar(FakedTrackingVariable trackingVariable) { Link Here
993
	if (this.parent instanceof BlockScope)
993
	if (this.parent instanceof BlockScope)
994
		((BlockScope)this.parent).removeTrackingVar(trackingVariable);
994
		((BlockScope)this.parent).removeTrackingVar(trackingVariable);
995
}
995
}
996
/** Unregister a wrapper resource without affecting its inner. */
997
public void pruneWrapperTrackingVar(FakedTrackingVariable trackingVariable) {
998
	this.trackingVariables.remove(trackingVariable);
999
}
996
/**
1000
/**
997
 * At the end of a block check the closing-status of all tracked closeables that are declared in this block.
1001
 * At the end of a block check the closing-status of all tracked closeables that are declared in this block.
998
 * Also invoked when entering unreachable code.
1002
 * Also invoked when entering unreachable code.

Return to bug 358903