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/NullReferenceTest.java (-1 / +64 lines)
Lines 47-53 Link Here
47
// Only the highest compliance level is run; add the VM argument
47
// Only the highest compliance level is run; add the VM argument
48
// -Dcompliance=1.4 (for example) to lower it if needed
48
// -Dcompliance=1.4 (for example) to lower it if needed
49
static {
49
static {
50
//		TESTS_NAMES = new String[] { "test358827" };
50
//		TESTS_NAMES = new String[] { "testBug360328" };
51
//		TESTS_NUMBERS = new int[] { 561 };
51
//		TESTS_NUMBERS = new int[] { 561 };
52
//		TESTS_RANGE = new int[] { 1, 2049 };
52
//		TESTS_RANGE = new int[] { 1, 2049 };
53
}
53
}
Lines 15124-15127 Link Here
15124
			true,
15124
			true,
15125
			compilerOptions);
15125
			compilerOptions);
15126
}
15126
}
15127
// Bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop)
15128
public void testBug360328() {
15129
	Map customOptions = getCompilerOptions();
15130
	customOptions.put(CompilerOptions.OPTION_ReportNullReference, CompilerOptions.ERROR);
15131
	customOptions.put(CompilerOptions.OPTION_ReportRedundantNullCheck, CompilerOptions.ERROR);
15132
	runNegativeTest(
15133
		true, /* flushOutputDir */
15134
		new String[] {
15135
			"X.java",
15136
			"public class X {\n" +
15137
			"    void print4() {\n" +
15138
			"        final String s1 = \"\";\n" +
15139
			"        for (int i=0; i<4; i++)\n" +
15140
			"            new Runnable() {\n" +
15141
			"                public void run() {\n" +
15142
			"                     if (s1 != null)\n" +
15143
			"                         s1.toString();\n" +
15144
			"                }\n" +
15145
			"            }.run();\n" + 
15146
			"    }\n" +
15147
			"    void print16(boolean b) {\n" +
15148
			"        final String s3 = b ? null : \"\";\n" +
15149
			"        for (int i=0; i<16; i++)\n" +
15150
			"            new Runnable() {\n" +
15151
			"                public void run() {\n" +
15152
			"                     s3.toString();\n" +
15153
			"                }\n" +
15154
			"            }.run();\n" + 
15155
			"    }\n" +
15156
			"    void print23() {\n" +
15157
			"        final String s23 = null;\n" +
15158
			"        for (int i=0; i<23; i++)\n" +
15159
			"            new Runnable() {\n" +
15160
			"                public void run() {\n" +
15161
			"                     s23.toString();\n" +
15162
			"                }\n" +
15163
			"            }.run();\n" + 
15164
			"    }\n" +
15165
			"}\n",
15166
15167
		},
15168
		null, /* classLibs */
15169
		customOptions,
15170
		"----------\n" + 
15171
		"1. ERROR in X.java (at line 7)\n" + 
15172
		"	if (s1 != null)\n" + 
15173
		"	    ^^\n" + 
15174
		"Redundant null check: The variable s1 cannot be null at this location\n" + 
15175
		"----------\n" + 
15176
		"2. ERROR in X.java (at line 17)\n" + 
15177
		"	s3.toString();\n" + 
15178
		"	^^\n" + 
15179
		"Potential null pointer access: The variable s3 may be null at this location\n" + 
15180
		"----------\n" + 
15181
		"3. ERROR in X.java (at line 26)\n" + 
15182
		"	s23.toString();\n" + 
15183
		"	^^^\n" + 
15184
		"Null pointer access: The variable s23 can only be null at this location\n" + 
15185
		"----------\n",
15186
		"",/* expected output */
15187
		"",/* expected error */
15188
	    JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
15189
}
15127
}
15190
}
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java (-4 lines)
Lines 12-19 Link Here
12
12
13
import org.eclipse.jdt.core.compiler.*;
13
import org.eclipse.jdt.core.compiler.*;
14
import org.eclipse.jdt.internal.compiler.*;
14
import org.eclipse.jdt.internal.compiler.*;
15
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
16
import org.eclipse.jdt.internal.compiler.flow.InitializationFlowContext;
17
import org.eclipse.jdt.internal.compiler.impl.*;
15
import org.eclipse.jdt.internal.compiler.impl.*;
18
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
16
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
19
import org.eclipse.jdt.internal.compiler.codegen.*;
17
import org.eclipse.jdt.internal.compiler.codegen.*;
Lines 68-75 Link Here
68
				throw new AbortMethod(this.compilationResult, problem);
66
				throw new AbortMethod(this.compilationResult, problem);
69
		}
67
		}
70
	}
68
	}
71
72
	public abstract void analyseCode(ClassScope classScope, InitializationFlowContext initializationContext, FlowInfo info);
73
69
74
	/**
70
	/**
75
	 * Bind and add argument's binding into the scope of the method
71
	 * Bind and add argument's binding into the scope of the method
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java (-3 / +3 lines)
Lines 16-23 Link Here
16
import org.eclipse.jdt.internal.compiler.CompilationResult;
16
import org.eclipse.jdt.internal.compiler.CompilationResult;
17
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
17
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
18
import org.eclipse.jdt.internal.compiler.flow.ExceptionHandlingFlowContext;
18
import org.eclipse.jdt.internal.compiler.flow.ExceptionHandlingFlowContext;
19
import org.eclipse.jdt.internal.compiler.flow.FlowContext;
19
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
20
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
20
import org.eclipse.jdt.internal.compiler.flow.InitializationFlowContext;
21
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
21
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
22
import org.eclipse.jdt.internal.compiler.lookup.Binding;
22
import org.eclipse.jdt.internal.compiler.lookup.Binding;
23
import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
23
import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
Lines 44-50 Link Here
44
		super(compilationResult);
44
		super(compilationResult);
45
	}
45
	}
46
46
47
	public void analyseCode(ClassScope classScope, InitializationFlowContext initializationContext, FlowInfo flowInfo) {
47
	public void analyseCode(ClassScope classScope, FlowContext flowContext, FlowInfo flowInfo) {
48
		// starting of the code analysis for methods
48
		// starting of the code analysis for methods
49
		if (this.ignoreFurtherInvestigation)
49
		if (this.ignoreFurtherInvestigation)
50
			return;
50
			return;
Lines 72-78 Link Here
72
72
73
			ExceptionHandlingFlowContext methodContext =
73
			ExceptionHandlingFlowContext methodContext =
74
				new ExceptionHandlingFlowContext(
74
				new ExceptionHandlingFlowContext(
75
					initializationContext,
75
					flowContext,
76
					this,
76
					this,
77
					this.binding.thrownExceptions,
77
					this.binding.thrownExceptions,
78
					null,
78
					null,
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java (-2 / +5 lines)
Lines 684-691 Link Here
684
			if (method.ignoreFurtherInvestigation)
684
			if (method.ignoreFurtherInvestigation)
685
				continue;
685
				continue;
686
			if (method.isInitializationMethod()) {
686
			if (method.isInitializationMethod()) {
687
				// pass down the appropriate initializerContext:
687
				if (method.isStatic()) { // <clinit>
688
				if (method.isStatic()) { // <clinit>
688
					method.analyseCode(
689
					((Clinit)method).analyseCode(
689
						this.scope,
690
						this.scope,
690
						staticInitializerContext,
691
						staticInitializerContext,
691
						staticFieldInfo.unconditionalInits().discardNonFieldInitializations().addInitializationsFrom(outerInfo));
692
						staticFieldInfo.unconditionalInits().discardNonFieldInitializations().addInitializationsFrom(outerInfo));
Lines 693-699 Link Here
693
					((ConstructorDeclaration)method).analyseCode(this.scope, initializerContext, constructorInfo.copy(), flowInfo.reachMode());
694
					((ConstructorDeclaration)method).analyseCode(this.scope, initializerContext, constructorInfo.copy(), flowInfo.reachMode());
694
				}
695
				}
695
			} else { // regular method
696
			} else { // regular method
696
				method.analyseCode(this.scope, null, flowInfo.copy());
697
				// pass down the parent flowContext UNLESS it is an initializer context:
698
				FlowContext parentContext = (flowContext instanceof InitializationFlowContext) ? null : flowContext;
699
				((MethodDeclaration)method).analyseCode(this.scope, parentContext, flowInfo.copy());
697
			}
700
			}
698
		}
701
		}
699
	}
702
	}

Return to bug 360328