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

Collapse All | Expand All

(-)a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java (+31 lines)
Lines 10-15 Link Here
10
 *     Stephan Herrmann - Contributions for
10
 *     Stephan Herrmann - Contributions for
11
 *     							bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used
11
 *     							bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used
12
 *      						bug 349326 - [1.7] new warning for missing try-with-resources
12
 *      						bug 349326 - [1.7] new warning for missing try-with-resources
13
 *      						bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop)
13
 *******************************************************************************/
14
 *******************************************************************************/
14
package org.eclipse.jdt.core.tests.compiler.regression;
15
package org.eclipse.jdt.core.tests.compiler.regression;
15
16
Lines 30-35 Link Here
30
31
31
public class FlowAnalysisTest extends AbstractRegressionTest {
32
public class FlowAnalysisTest extends AbstractRegressionTest {
32
static {
33
static {
34
//	TESTS_NAMES = new String[] { "testLocalClassInInitializer1" };
33
//	TESTS_NUMBERS = new int[] { 69 };
35
//	TESTS_NUMBERS = new int[] { 69 };
34
}
36
}
35
public FlowAnalysisTest(String name) {
37
public FlowAnalysisTest(String name) {
Lines 2408-2413 Link Here
2408
			}, 
2410
			}, 
2409
			"");	
2411
			"");	
2410
}
2412
}
2413
// Bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop)
2414
// return/break/continue inside anonymous class inside try-catch inside initializer
2415
public void testLocalClassInInitializer1() {
2416
	this.runConformTest(
2417
			new String[] {
2418
				"X.java",
2419
				"public class X {\n" +
2420
				"    static {\n" +
2421
				"        final int i=4;\n" +
2422
				"        try {\n" +
2423
				"            Runnable runner = new Runnable() {\n" +
2424
				"                public void run() {\n" +
2425
				"                    switch (i) {" +
2426
				"                        case 4: break;\n" +
2427
				"                    }\n" +
2428
				"                    int j = i;\n" +
2429
				"                    while (j++ < 10) {\n" +
2430
				"                        if (j == 2) continue;\n" +
2431
				"                        if (j == 4) break;\n" +
2432
				"                        if (j == 6) return;\n" +
2433
				"                    }\n" +
2434
				"                }\n" +
2435
				"            };\n" +
2436
				"        } catch (RuntimeException re) {}\n" +
2437
				"    }\n" +
2438
				"}\n"
2439
			}, 
2440
			"");	
2441
}
2411
public static Class testClass() {
2442
public static Class testClass() {
2412
	return FlowAnalysisTest.class;
2443
	return FlowAnalysisTest.class;
2413
}
2444
}
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java (-3 / +8 lines)
Lines 10-15 Link Here
10
 *     Stephan Herrmann - Contributions for 
10
 *     Stephan Herrmann - Contributions for 
11
 *     							bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
11
 *     							bug 319201 - [null] no warning when unboxing SingleNameReference causes NPE
12
 *     							bug 349326 - [1.7] new warning for missing try-with-resources
12
 *     							bug 349326 - [1.7] new warning for missing try-with-resources
13
 *     							bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop)
13
 *******************************************************************************/
14
 *******************************************************************************/
14
package org.eclipse.jdt.internal.compiler.ast;
15
package org.eclipse.jdt.internal.compiler.ast;
15
16
Lines 37-42 Link Here
37
38
38
	// lookup the label, this should answer the returnContext
39
	// lookup the label, this should answer the returnContext
39
40
41
	MethodScope methodScope = currentScope.methodScope();
42
	AbstractMethodDeclaration referenceMethod = methodScope.referenceMethod();
40
	if (this.expression != null) {
43
	if (this.expression != null) {
41
		flowInfo = this.expression.analyseCode(currentScope, flowContext, flowInfo);
44
		flowInfo = this.expression.analyseCode(currentScope, flowContext, flowInfo);
42
		if ((this.expression.implicitConversion & TypeIds.UNBOXING) != 0) {
45
		if ((this.expression.implicitConversion & TypeIds.UNBOXING) != 0) {
Lines 44-50 Link Here
44
		}
47
		}
45
		FakedTrackingVariable trackingVariable = FakedTrackingVariable.getCloseTrackingVariable(this.expression);
48
		FakedTrackingVariable trackingVariable = FakedTrackingVariable.getCloseTrackingVariable(this.expression);
46
		if (trackingVariable != null) {
49
		if (trackingVariable != null) {
47
			if (currentScope.methodScope() != trackingVariable.methodScope)
50
			if (methodScope != trackingVariable.methodScope)
48
				trackingVariable.markClosedInNestedMethod();
51
				trackingVariable.markClosedInNestedMethod();
49
			// don't report issues concerning this local, since by returning
52
			// don't report issues concerning this local, since by returning
50
			// the method passes the responsibility to the caller:
53
			// the method passes the responsibility to the caller:
Lines 52-58 Link Here
52
		}
55
		}
53
	}
56
	}
54
	this.initStateIndex =
57
	this.initStateIndex =
55
		currentScope.methodScope().recordInitializationStates(flowInfo);
58
		methodScope.recordInitializationStates(flowInfo);
56
	// compute the return sequence (running the finally blocks)
59
	// compute the return sequence (running the finally blocks)
57
	FlowContext traversedContext = flowContext;
60
	FlowContext traversedContext = flowContext;
58
	int subCount = 0;
61
	int subCount = 0;
Lines 89-101 Link Here
89
					}
92
					}
90
					saveValueNeeded = true;
93
					saveValueNeeded = true;
91
					this.initStateIndex =
94
					this.initStateIndex =
92
						currentScope.methodScope().recordInitializationStates(flowInfo);
95
						methodScope.recordInitializationStates(flowInfo);
93
				}
96
				}
94
			}
97
			}
95
		} else if (traversedContext instanceof InitializationFlowContext) {
98
		} else if (traversedContext instanceof InitializationFlowContext) {
96
				currentScope.problemReporter().cannotReturnInInitializer(this);
99
				currentScope.problemReporter().cannotReturnInInitializer(this);
97
				return FlowInfo.DEAD_END;
100
				return FlowInfo.DEAD_END;
98
		}
101
		}
102
		if (traversedContext.associatedNode == referenceMethod)
103
			break; // don't traverse beyond the enclosing method (see https://bugs.eclipse.org/360328).
99
	} while ((traversedContext = traversedContext.parent) != null);
104
	} while ((traversedContext = traversedContext.parent) != null);
100
105
101
	// resize subroutines
106
	// resize subroutines

Return to bug 360328