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

Collapse All | Expand All

(-)src/org/eclipse/jdt/core/tests/compiler/regression/AssignmentTest.java (-1 / +1 lines)
Lines 188-194 Link Here
188
		"2. ERROR in X.java (at line 9)\n" + 
188
		"2. ERROR in X.java (at line 9)\n" + 
189
		"	if(a!=null)\n" + 
189
		"	if(a!=null)\n" + 
190
		"	   ^\n" + 
190
		"	   ^\n" + 
191
		"The variable a can only be null; it was either set to null or checked for null when last used\n" + 
191
		"The variable a cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + 
192
		"----------\n" + 
192
		"----------\n" + 
193
		"3. ERROR in X.java (at line 13)\n" + 
193
		"3. ERROR in X.java (at line 13)\n" + 
194
		"	System.out.println(a+b);\n" + 
194
		"	System.out.println(a+b);\n" + 
(-)src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java (-46 / +48 lines)
Lines 33-39 Link Here
33
  	// -Dcompliance=1.4 (for example) to lower it if needed
33
  	// -Dcompliance=1.4 (for example) to lower it if needed
34
  	static {
34
  	static {
35
//    	TESTS_NAMES = new String[] { "test011" };
35
//    	TESTS_NAMES = new String[] { "test011" };
36
//    	TESTS_NUMBERS = new int[] { 729 };   
36
//    	TESTS_NUMBERS = new int[] { 333 };   
37
//    	TESTS_NUMBERS = new int[] { 2999 };   
37
//    	TESTS_NUMBERS = new int[] { 2999 };   
38
//    	TESTS_RANGE = new int[] { 2050, -1 }; 
38
//    	TESTS_RANGE = new int[] { 2050, -1 }; 
39
//  	TESTS_RANGE = new int[] { 1, 2049 }; 
39
//  	TESTS_RANGE = new int[] { 1, 2049 }; 
Lines 1223-1233 Link Here
1223
		"	if (o == null && o == null) {\n" + 
1223
		"	if (o == null && o == null) {\n" + 
1224
		"	                 ^\n" + 
1224
		"	                 ^\n" + 
1225
		"The variable o can only be null; it was either set to null or checked for null when last used\n" + 
1225
		"The variable o can only be null; it was either set to null or checked for null when last used\n" + 
1226
		"----------\n" + 
1227
		"2. ERROR in X.java (at line 6)\n" + 
1228
		"	if (o == null) { /* */ }\n" + 
1229
		"	    ^\n" + 
1230
		"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + 
1231
		"----------\n");
1226
		"----------\n");
1232
}
1227
}
1233
1228
Lines 1601-1615 Link Here
1601
}
1596
}
1602
1597
1603
// null analysis - if/else
1598
// null analysis - if/else
1604
// PMT: exactly the case we talked about; what happens is that the first
1599
// rationale: erroneous tests no more change null status
1605
// if shade doubts upon o; what we could do is to avoid marking in case
1606
// of error? not sure this is appropriate though, because of inner code
1607
// into the if itself; I believe I somewhat did that on purpose: the latest
1608
// wins; completed with o.toString()...
1609
// basically, the choice is about what we should do in case of error:
1610
// neglect the effect of the error, or propagate this effect; the second
1611
//  tends to produce less repeated errors (I believe) than the first...
1612
// PREMATURE could refine adding a null-dependent reachable mark... not urgent
1613
public void test0312_if_else() {
1600
public void test0312_if_else() {
1614
	this.runNegativeTest(
1601
	this.runNegativeTest(
1615
		new String[] {
1602
		new String[] {
Lines 1619-1626 Link Here
1619
			"  void foo() {\n" + 
1606
			"  void foo() {\n" + 
1620
			"    Object o = new Object();\n" + 
1607
			"    Object o = new Object();\n" + 
1621
			"    if (o == null) { /* */ }\n" + // complain 
1608
			"    if (o == null) { /* */ }\n" + // complain 
1622
			"    if (o != null) { /* */ }\n" + // quiet
1609
			"    if (o != null) { /* */ }\n" + // complain
1623
			"    o.toString();\n" + // complain
1610
			"    o.toString();\n" + // quiet
1624
			"  }\n" + 
1611
			"  }\n" + 
1625
			"}\n"},
1612
			"}\n"},
1626
		"----------\n" + 
1613
		"----------\n" + 
Lines 1629-1638 Link Here
1629
		"	    ^\n" + 
1616
		"	    ^\n" + 
1630
		"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + 
1617
		"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + 
1631
		"----------\n" + 
1618
		"----------\n" + 
1632
		"2. ERROR in X.java (at line 7)\n" + 
1619
		"2. ERROR in X.java (at line 6)\n" + 
1633
		"	o.toString();\n" + 
1620
		"	if (o != null) { /* */ }\n" + 
1634
		"	^\n" + 
1621
		"	    ^\n" + 
1635
		"The variable o may be null\n" + 
1622
		"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + 
1636
		"----------\n");
1623
		"----------\n");
1637
}
1624
}
1638
 
1625
 
Lines 2062-2067 Link Here
2062
		"----------\n");
2049
		"----------\n");
2063
}
2050
}
2064
2051
2052
// null analysis - if/else
2053
// avoid double diagnostic (Frédéric)
2054
public void test0333_if_else() {
2055
	this.runNegativeTest(
2056
		new String[] {
2057
			"X.java",
2058
			"public class X {\n" + 
2059
			"  void foo(Object[] o) {\n" + 
2060
			"    if (o != null) {\n" +
2061
			"      int length = o == null ? 0 : o.length;\n" + // complain
2062
			"      for (int i = 0; i < length; i++) {\n" +
2063
			"        o[i].toString();\n" + 	// quiet, protected by if above
2064
			"      }\n" + 
2065
			"    }\n" + 
2066
			"  }\n" + 
2067
			"}"},
2068
		"----------\n" + 
2069
		"1. ERROR in X.java (at line 4)\n" + 
2070
		"	int length = o == null ? 0 : o.length;\n" + 
2071
		"	             ^\n" + 
2072
		"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + 
2073
		"----------\n");
2074
}
2075
2065
// null analysis -- while
2076
// null analysis -- while
2066
public void test0401_while() {
2077
public void test0401_while() {
2067
	this.runNegativeTest(
2078
	this.runNegativeTest(
Lines 2551-2557 Link Here
2551
}
2562
}
2552
2563
2553
// null analysis -- while
2564
// null analysis -- while
2554
// REVIEW we get one extraneous message that looks a bit strange
2555
public void test0423_while() {
2565
public void test0423_while() {
2556
	this.runNegativeTest(
2566
	this.runNegativeTest(
2557
		new String[] {
2567
		new String[] {
Lines 2572-2582 Link Here
2572
		"	if (o == null) { /* */ }\n" + 
2582
		"	if (o == null) { /* */ }\n" + 
2573
		"	    ^\n" + 
2583
		"	    ^\n" + 
2574
		"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + 
2584
		"The variable o cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + 
2575
		"----------\n" + 
2576
		"2. ERROR in X.java (at line 8)\n" + 
2577
		"	o = null;\n" + 
2578
		"	^\n" + 
2579
		"The variable o can only be null; it was either set to null or checked for null when last used\n" + 
2580
		"----------\n");
2585
		"----------\n");
2581
}
2586
}
2582
2587
Lines 5230-5235 Link Here
5230
}
5235
}
5231
5236
5232
// moved from AssignmentTest
5237
// moved from AssignmentTest
5238
// new policy (do not modify null info in case of problem in comparison)
5239
// removes errors on 8 - which is better, and 3 - which might be
5240
// questionable
5233
public void test1004() {
5241
public void test1004() {
5234
	this.runNegativeTest(
5242
	this.runNegativeTest(
5235
		new String[] {
5243
		new String[] {
Lines 5261-5280 Link Here
5261
		"	    ^\n" + 
5269
		"	    ^\n" + 
5262
		"The variable x cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + 
5270
		"The variable x cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + 
5263
		"----------\n" + 
5271
		"----------\n" + 
5264
		"3. ERROR in X.java (at line 6)\n" + 
5272
		"3. ERROR in X.java (at line 9)\n" + 
5265
		"	x.foo(null); // 3\n" + 
5266
		"	^\n" + 
5267
		"The variable x can only be null; it was either set to null or checked for null when last used\n" + 
5268
		"----------\n" + 
5269
		"4. ERROR in X.java (at line 9)\n" + 
5270
		"	} else if (x != null) { // 6\n" + 
5273
		"	} else if (x != null) { // 6\n" + 
5271
		"	           ^\n" + 
5274
		"	           ^\n" + 
5272
		"The variable x cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + 
5275
		"The variable x cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + 
5273
		"----------\n" + 
5274
		"5. ERROR in X.java (at line 12)\n" + 
5275
		"	x.foo(null); // 8\n" + 
5276
		"	^\n" + 
5277
		"The variable x may be null\n" + 
5278
		"----------\n");
5276
		"----------\n");
5279
}
5277
}
5280
5278
Lines 5428-5433 Link Here
5428
		"	if (other != null) {\n" + 
5426
		"	if (other != null) {\n" + 
5429
		"	    ^^^^^\n" + 
5427
		"	    ^^^^^\n" + 
5430
		"The variable other cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + 
5428
		"The variable other cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + 
5429
		"----------\n" + 
5430
		"2. ERROR in X.java (at line 11)\n" + 
5431
		"	if (other == null) {\n" + 
5432
		"	    ^^^^^\n" + 
5433
		"The variable other cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + 
5431
		"----------\n");
5434
		"----------\n");
5432
}
5435
}
5433
5436
Lines 5459-5465 Link Here
5459
	);
5462
	);
5460
}
5463
}
5461
5464
5462
// REVIEW here we do not catch the dead branch: x cannot equal this then null with no assignment in between
5463
public void test1013() {
5465
public void test1013() {
5464
	this.runNegativeTest(
5466
	this.runNegativeTest(
5465
		new String[] {
5467
		new String[] {
Lines 5478-5488 Link Here
5478
		"	if (x == null) {\n" + 
5480
		"	if (x == null) {\n" + 
5479
		"	    ^\n" + 
5481
		"	    ^\n" + 
5480
		"The variable x cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + 
5482
		"The variable x cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + 
5481
		"----------\n" + 
5482
		"2. ERROR in X.java (at line 5)\n" + 
5483
		"	x.foo(this);\n" + 
5484
		"	^\n" + 
5485
		"The variable x can only be null; it was either set to null or checked for null when last used\n" + 
5486
		"----------\n");
5483
		"----------\n");
5487
}
5484
}
5488
5485
Lines 5988-5994 Link Here
5988
		"2. ERROR in X.java (at line 8)\n" + 
5985
		"2. ERROR in X.java (at line 8)\n" + 
5989
		"	if(a!=null)\n" + 
5986
		"	if(a!=null)\n" + 
5990
		"	   ^\n" + 
5987
		"	   ^\n" + 
5991
		"The variable a can only be null; it was either set to null or checked for null when last used\n" + 
5988
		"The variable a cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + 
5992
		"----------\n");
5989
		"----------\n");
5993
}
5990
}
5994
5991
Lines 6082-6088 Link Here
6082
			"      o60 = o0, o61 = o0, o62 = o0, o63 = o0, o64 = o0,\n" + 
6079
			"      o60 = o0, o61 = o0, o62 = o0, o63 = o0, o64 = o0,\n" + 
6083
			"      o65 = o0, o66 = o0, o67 = o0, o68 = o0, o69 = o0;\n" + 
6080
			"      o65 = o0, o66 = o0, o67 = o0, o68 = o0, o69 = o0;\n" + 
6084
			"    if (o65 == null) { /* */ }\n" + // complain 
6081
			"    if (o65 == null) { /* */ }\n" + // complain 
6085
			"    if (o65 != null) { /* */ }\n" + // quiet (already reported)
6082
			"    if (o65 != null) { /* */ }\n" + // complain
6086
			"  }\n" + 
6083
			"  }\n" + 
6087
			"}\n"},
6084
			"}\n"},
6088
		"----------\n" + 
6085
		"----------\n" + 
Lines 6090-6095 Link Here
6090
		"	if (o65 == null) { /* */ }\n" + 
6087
		"	if (o65 == null) { /* */ }\n" + 
6091
		"	    ^^^\n" + 
6088
		"	    ^^^\n" + 
6092
		"The variable o65 cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + 
6089
		"The variable o65 cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + 
6090
		"----------\n" + 
6091
		"2. ERROR in X.java (at line 19)\n" + 
6092
		"	if (o65 != null) { /* */ }\n" + 
6093
		"	    ^^^\n" + 
6094
		"The variable o65 cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + 
6093
		"----------\n");
6095
		"----------\n");
6094
}
6096
}
6095
6097
(-)compiler/org/eclipse/jdt/internal/compiler/ast/EqualExpression.java (-11 / +14 lines)
Lines 36-55 Link Here
36
	private void checkVariableComparison(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo, FlowInfo initsWhenTrue, FlowInfo initsWhenFalse, LocalVariableBinding local, int nullStatus, Expression reference) {
36
	private void checkVariableComparison(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo, FlowInfo initsWhenTrue, FlowInfo initsWhenFalse, LocalVariableBinding local, int nullStatus, Expression reference) {
37
		switch (nullStatus) {
37
		switch (nullStatus) {
38
			case FlowInfo.NULL :
38
			case FlowInfo.NULL :
39
				flowContext.recordUsingNullReference(scope, local, reference, 
39
				if (!flowContext.recordUsingNullReference(scope, local, reference, 
40
					FlowContext.CAN_ONLY_NULL_NON_NULL, flowInfo);
40
						FlowContext.CAN_ONLY_NULL_NON_NULL, flowInfo)) {
41
				if (((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) {
41
					// no error reported (yet), mark downstream flow
42
					initsWhenTrue.markAsComparedEqualToNull(local); // from thereon it is set
42
					// WORK consider inverting the logic - saves a not operation
43
					initsWhenFalse.markAsComparedEqualToNonNull(local); // from thereon it is set
43
					if (((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) {
44
				} else {
44
						initsWhenTrue.markAsComparedEqualToNull(local); // from thereon it is set
45
					initsWhenTrue.markAsComparedEqualToNonNull(local); // from thereon it is set
45
						initsWhenFalse.markAsComparedEqualToNonNull(local); // from thereon it is set
46
					initsWhenFalse.markAsComparedEqualToNull(local); // from thereon it is set
46
					} else {
47
						initsWhenTrue.markAsComparedEqualToNonNull(local); // from thereon it is set
48
						initsWhenFalse.markAsComparedEqualToNull(local); // from thereon it is set
49
					}
47
				}
50
				}
48
				break;
51
				break;
49
			case FlowInfo.NON_NULL :
52
			case FlowInfo.NON_NULL :
50
				flowContext.recordUsingNullReference(scope, local, reference, 
53
				if (!flowContext.recordUsingNullReference(scope, local, reference, 
51
					FlowContext.CAN_ONLY_NULL, flowInfo);
54
							FlowContext.CAN_ONLY_NULL, flowInfo)
52
				if (((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) {
55
						&& ((this.bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) {
53
					initsWhenTrue.markAsComparedEqualToNonNull(local); // from thereon it is set
56
					initsWhenTrue.markAsComparedEqualToNonNull(local); // from thereon it is set
54
				}
57
				}
55
				break;
58
				break;
(-)compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java (-10 / +12 lines)
Lines 186-192 Link Here
186
		return true;
186
		return true;
187
	}
187
	}
188
188
189
	public void recordUsingNullReference(Scope scope, LocalVariableBinding local, 
189
	public boolean recordUsingNullReference(Scope scope, LocalVariableBinding local, 
190
			Expression reference, int checkType, FlowInfo flowInfo) {
190
			Expression reference, int checkType, FlowInfo flowInfo) {
191
		if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0)	{
191
		if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0)	{
192
		if (deferNullDiagnostic) { // within an enclosing loop, be conservative
192
		if (deferNullDiagnostic) { // within an enclosing loop, be conservative
Lines 196-216 Link Here
196
					if (flowInfo.isProtectedNonNull(local)) {
196
					if (flowInfo.isProtectedNonNull(local)) {
197
						if (checkType == CAN_ONLY_NULL_NON_NULL) {
197
						if (checkType == CAN_ONLY_NULL_NON_NULL) {
198
							scope.problemReporter().localVariableCannotBeNull(local, reference);
198
							scope.problemReporter().localVariableCannotBeNull(local, reference);
199
							return true;
199
						}
200
						}
200
						return;
201
						return false;
201
					}
202
					}
202
					if (flowInfo.isProtectedNull(local)) {
203
					if (flowInfo.isProtectedNull(local)) {
203
						scope.problemReporter().localVariableCanOnlyBeNull(local, reference);
204
						scope.problemReporter().localVariableCanOnlyBeNull(local, reference);
204
						return;
205
						return true;
205
					}
206
					}
206
					break;
207
					break;
207
				case MAY_NULL :
208
				case MAY_NULL :
208
					if (flowInfo.isProtectedNonNull(local)) {
209
					if (flowInfo.isProtectedNonNull(local)) {
209
						return;
210
						return false;
210
					}
211
					}
211
					if (flowInfo.isProtectedNull(local)) {
212
					if (flowInfo.isProtectedNull(local)) {
212
						scope.problemReporter().localVariableCanOnlyBeNull(local, reference);
213
						scope.problemReporter().localVariableCanOnlyBeNull(local, reference);
213
						return;
214
						return true;
214
					}
215
					}
215
					break;
216
					break;
216
				default:
217
				default:
Lines 222-246 Link Here
222
				case CAN_ONLY_NULL_NON_NULL :
223
				case CAN_ONLY_NULL_NON_NULL :
223
					if (flowInfo.isDefinitelyNonNull(local)) {
224
					if (flowInfo.isDefinitelyNonNull(local)) {
224
						scope.problemReporter().localVariableCannotBeNull(local, reference);				
225
						scope.problemReporter().localVariableCannotBeNull(local, reference);				
225
						return;
226
						return true;
226
					}
227
					}
227
				case CAN_ONLY_NULL:
228
				case CAN_ONLY_NULL:
228
					if (flowInfo.isDefinitelyNull(local)) {
229
					if (flowInfo.isDefinitelyNull(local)) {
229
						scope.problemReporter().localVariableCanOnlyBeNull(local, reference);
230
						scope.problemReporter().localVariableCanOnlyBeNull(local, reference);
230
						return;
231
						return true;
231
					}
232
					}
232
					break;
233
					break;
233
				case MAY_NULL :
234
				case MAY_NULL :
234
					if (flowInfo.isDefinitelyNull(local)) {
235
					if (flowInfo.isDefinitelyNull(local)) {
235
						scope.problemReporter().localVariableCanOnlyBeNull(local, reference);
236
						scope.problemReporter().localVariableCanOnlyBeNull(local, reference);
236
						return;
237
						return true;
237
					}
238
					}
238
					if (flowInfo.isPotentiallyNull(local)) {
239
					if (flowInfo.isPotentiallyNull(local)) {
239
						scope.problemReporter().localVariableMayBeNull(local, reference);
240
						scope.problemReporter().localVariableMayBeNull(local, reference);
240
						return;
241
						return true;
241
					}
242
					}
242
					if (flowInfo.isDefinitelyNonNull(local)) {
243
					if (flowInfo.isDefinitelyNonNull(local)) {
243
						return; // shortcut: cannot be null
244
						return false; // shortcut: cannot be null
244
					}
245
					}
245
					break;
246
					break;
246
				default:
247
				default:
Lines 250-255 Link Here
250
		recordNullReference(local, reference, checkType); 
251
		recordNullReference(local, reference, checkType); 
251
		// prepare to re-check with try/catch flow info
252
		// prepare to re-check with try/catch flow info
252
		}
253
		}
254
		return false;
253
	}
255
	}
254
	
256
	
255
	void removeFinalAssignmentIfAny(Reference reference) {
257
	void removeFinalAssignmentIfAny(Reference reference) {
(-)compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java (-10 / +12 lines)
Lines 303-313 Link Here
303
	nullCheckTypes[nullCount++] = status;
303
	nullCheckTypes[nullCount++] = status;
304
}
304
}
305
	
305
	
306
public void recordUsingNullReference(Scope scope, LocalVariableBinding local,
306
public boolean recordUsingNullReference(Scope scope, LocalVariableBinding local,
307
		Expression reference, int checkType, FlowInfo flowInfo) {
307
		Expression reference, int checkType, FlowInfo flowInfo) {
308
	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0 || 
308
	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0 || 
309
			flowInfo.isDefinitelyUnknown(local)) {
309
			flowInfo.isDefinitelyUnknown(local)) {
310
		return;
310
		return false;
311
	}
311
	}
312
	switch (checkType) {
312
	switch (checkType) {
313
		case CAN_ONLY_NULL_NON_NULL :
313
		case CAN_ONLY_NULL_NON_NULL :
Lines 315-349 Link Here
315
			if (flowInfo.isDefinitelyNonNull(local)) {
315
			if (flowInfo.isDefinitelyNonNull(local)) {
316
				if (checkType == CAN_ONLY_NULL_NON_NULL) {
316
				if (checkType == CAN_ONLY_NULL_NON_NULL) {
317
					scope.problemReporter().localVariableCannotBeNull(local, reference);
317
					scope.problemReporter().localVariableCannotBeNull(local, reference);
318
					return true;
318
				}
319
				}
319
				return;
320
				return false;
320
			}
321
			}
321
			if (flowInfo.isDefinitelyNull(local)) {
322
			if (flowInfo.isDefinitelyNull(local)) {
322
				scope.problemReporter().localVariableCanOnlyBeNull(local, reference);
323
				scope.problemReporter().localVariableCanOnlyBeNull(local, reference);
323
				return;
324
				return true;
324
			}
325
			}
325
			if (flowInfo.isPotentiallyUnknown(local)) {
326
			if (flowInfo.isPotentiallyUnknown(local)) {
326
				return;
327
				return false;
327
			}
328
			}
328
			recordNullReference(local, reference, checkType);
329
			recordNullReference(local, reference, checkType);
329
			return;
330
			return false;
330
		case MAY_NULL :
331
		case MAY_NULL :
331
			if (flowInfo.isDefinitelyNonNull(local)) {
332
			if (flowInfo.isDefinitelyNonNull(local)) {
332
				return;
333
				return false;
333
			}
334
			}
334
			if (flowInfo.isDefinitelyNull(local)) {
335
			if (flowInfo.isDefinitelyNull(local)) {
335
				scope.problemReporter().localVariableCanOnlyBeNull(local, reference);
336
				scope.problemReporter().localVariableCanOnlyBeNull(local, reference);
336
				return;
337
				return true;
337
			}
338
			}
338
			if (flowInfo.isPotentiallyNull(local)) {
339
			if (flowInfo.isPotentiallyNull(local)) {
339
				scope.problemReporter().localVariableMayBeNull(local, reference);
340
				scope.problemReporter().localVariableMayBeNull(local, reference);
340
				return;
341
				return true;
341
			}
342
			}
342
			recordNullReference(local, reference, checkType);
343
			recordNullReference(local, reference, checkType);
343
			return;
344
			return false;
344
		default:
345
		default:
345
			// never happens
346
			// never happens
346
	}
347
	}
348
	return false;
347
}
349
}
348
	
350
	
349
	void removeFinalAssignmentIfAny(Reference reference) {
351
	void removeFinalAssignmentIfAny(Reference reference) {
(-)compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java (-9 / +11 lines)
Lines 472-519 Link Here
472
 *  	perform supplementary checks against flow info instances that cannot
472
 *  	perform supplementary checks against flow info instances that cannot
473
 *  	be known at the time of calling this method (they are influenced by
473
 *  	be known at the time of calling this method (they are influenced by
474
 * 		code that follows the current point)
474
 * 		code that follows the current point)
475
 * @return true if a problem has been reported, false else
475
 */
476
 */
476
public void recordUsingNullReference(Scope scope, LocalVariableBinding local, 
477
public boolean recordUsingNullReference(Scope scope, LocalVariableBinding local, 
477
		Expression reference, int checkType, FlowInfo flowInfo) {
478
		Expression reference, int checkType, FlowInfo flowInfo) {
478
	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0 || 
479
	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0 || 
479
			flowInfo.isDefinitelyUnknown(local)) {
480
			flowInfo.isDefinitelyUnknown(local)) {
480
		return;
481
		return false;
481
	}
482
	}
482
	switch (checkType) {
483
	switch (checkType) {
483
		case CAN_ONLY_NULL_NON_NULL :
484
		case CAN_ONLY_NULL_NON_NULL :
484
			if (flowInfo.isDefinitelyNonNull(local)) {
485
			if (flowInfo.isDefinitelyNonNull(local)) {
485
				scope.problemReporter().localVariableCannotBeNull(local, reference);				
486
				scope.problemReporter().localVariableCannotBeNull(local, reference);				
486
				return;
487
				return true;
487
			}
488
			}
488
			else if (flowInfo.isPotentiallyUnknown(local)) {
489
			else if (flowInfo.isPotentiallyUnknown(local)) {
489
				return;
490
				return false;
490
			}
491
			}
491
		case CAN_ONLY_NULL:
492
		case CAN_ONLY_NULL:
492
			if (flowInfo.isDefinitelyNull(local)) {
493
			if (flowInfo.isDefinitelyNull(local)) {
493
				scope.problemReporter().localVariableCanOnlyBeNull(local, reference);
494
				scope.problemReporter().localVariableCanOnlyBeNull(local, reference);
494
				return;
495
				return true;
495
			}
496
			}
496
			else if (flowInfo.isPotentiallyUnknown(local)) {
497
			else if (flowInfo.isPotentiallyUnknown(local)) {
497
				return;
498
				return false;
498
			}
499
			}
499
			break;
500
			break;
500
		case MAY_NULL :
501
		case MAY_NULL :
501
			if (flowInfo.isDefinitelyNull(local)) {
502
			if (flowInfo.isDefinitelyNull(local)) {
502
				scope.problemReporter().localVariableCanOnlyBeNull(local, reference);
503
				scope.problemReporter().localVariableCanOnlyBeNull(local, reference);
503
				return;
504
				return true;
504
			}
505
			}
505
			if (flowInfo.isPotentiallyNull(local)) {
506
			if (flowInfo.isPotentiallyNull(local)) {
506
				scope.problemReporter().localVariableMayBeNull(local, reference);
507
				scope.problemReporter().localVariableMayBeNull(local, reference);
507
				return;
508
				return false;
508
			}
509
			}
509
			break;
510
			break;
510
		default:
511
		default:
511
			// never happens
512
			// never happens
512
	}
513
	}
513
	if (parent != null) {
514
	if (parent != null) {
514
		parent.recordUsingNullReference(scope, local, reference, checkType, 
515
		return parent.recordUsingNullReference(scope, local, reference, checkType, 
515
				flowInfo);
516
				flowInfo);
516
	}
517
	}
518
	return false;
517
}
519
}
518
520
519
void removeFinalAssignmentIfAny(Reference reference) {
521
void removeFinalAssignmentIfAny(Reference reference) {

Return to bug 110030