View | Details | Raw Unified | Return to bug 149665
Collapse All | Expand All

(-)src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTests.java (-4 / +16 lines)
Lines 651-657 Link Here
651
					isPotentiallyNull = state.isPotentiallyNull(TestLocalVariableBinding.local0),
651
					isPotentiallyNull = state.isPotentiallyNull(TestLocalVariableBinding.local0),
652
					isPotentiallyUnknown = state.isPotentiallyUnknown(TestLocalVariableBinding.local0),
652
					isPotentiallyUnknown = state.isPotentiallyUnknown(TestLocalVariableBinding.local0),
653
					isProtectedNonNull = state.isProtectedNonNull(TestLocalVariableBinding.local0),
653
					isProtectedNonNull = state.isProtectedNonNull(TestLocalVariableBinding.local0),
654
					isProtectedNull = state.isProtectedNull(TestLocalVariableBinding.local0);
654
					isProtectedNull = state.isProtectedNull(TestLocalVariableBinding.local0),
655
					cannotBeNull = state.cannotBeNull(TestLocalVariableBinding.local0),
656
					canOnlyBeNull = state.canOnlyBeNull(TestLocalVariableBinding.local0);
655
				if (isDefinitelyNonNull
657
				if (isDefinitelyNonNull
656
							&& (isDefinitelyNull || isDefinitelyUnknown
658
							&& (isDefinitelyNull || isDefinitelyUnknown
657
									|| isPotentiallyNull
659
									|| isPotentiallyNull
Lines 688-694 Link Here
688
							&& !(isDefinitelyNonNull || isDefinitelyNull
690
							&& !(isDefinitelyNonNull || isDefinitelyNull
689
									|| isDefinitelyUnknown || isPotentiallyNull
691
									|| isDefinitelyUnknown || isPotentiallyNull
690
									|| isPotentiallyUnknown || isProtectedNonNull
692
									|| isPotentiallyUnknown || isProtectedNonNull
691
									|| isProtectedNull)) {
693
									|| isProtectedNull)
694
						|| cannotBeNull != (isProtectedNonNull || 
695
								isDefinitelyNonNull)
696
						|| canOnlyBeNull != (isProtectedNull || 
697
								isDefinitelyNull)) {
692
					if (failures == 0) {
698
					if (failures == 0) {
693
						System.out.println(header);
699
						System.out.println(header);
694
					}
700
					}
Lines 714-720 Link Here
714
				isPotentiallyNull = state.isPotentiallyNull(TestLocalVariableBinding.local64),
720
				isPotentiallyNull = state.isPotentiallyNull(TestLocalVariableBinding.local64),
715
				isPotentiallyUnknown = state.isPotentiallyUnknown(TestLocalVariableBinding.local64),
721
				isPotentiallyUnknown = state.isPotentiallyUnknown(TestLocalVariableBinding.local64),
716
				isProtectedNonNull = state.isProtectedNonNull(TestLocalVariableBinding.local64),
722
				isProtectedNonNull = state.isProtectedNonNull(TestLocalVariableBinding.local64),
717
				isProtectedNull = state.isProtectedNull(TestLocalVariableBinding.local64);
723
				isProtectedNull = state.isProtectedNull(TestLocalVariableBinding.local64),
724
				cannotBeNull = state.cannotBeNull(TestLocalVariableBinding.local64),
725
				canOnlyBeNull = state.canOnlyBeNull(TestLocalVariableBinding.local64);
718
				if (isDefinitelyNonNull
726
				if (isDefinitelyNonNull
719
							&& (isDefinitelyNull || isDefinitelyUnknown
727
							&& (isDefinitelyNull || isDefinitelyUnknown
720
									|| isPotentiallyNull
728
									|| isPotentiallyNull
Lines 751-757 Link Here
751
							&& !(isDefinitelyNonNull || isDefinitelyNull
759
							&& !(isDefinitelyNonNull || isDefinitelyNull
752
									|| isDefinitelyUnknown || isPotentiallyNull
760
									|| isDefinitelyUnknown || isPotentiallyNull
753
									|| isPotentiallyUnknown || isProtectedNonNull
761
									|| isPotentiallyUnknown || isProtectedNonNull
754
									|| isProtectedNull)) {
762
									|| isProtectedNull)
763
									|| cannotBeNull != (isProtectedNonNull || 
764
											isDefinitelyNonNull)
765
									|| canOnlyBeNull != (isProtectedNull || 
766
											isDefinitelyNull)) {
755
					if (failures == 0) {
767
					if (failures == 0) {
756
						System.out.println(header);
768
						System.out.println(header);
757
					}
769
					}
(-)src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java (+127 lines)
Lines 4322-4327 Link Here
4322
		"");
4322
		"");
4323
}
4323
}
4324
4324
4325
// null analysis -- try/finally
4326
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=149665
4327
// incorrect analysis within try finally with an embedded && expression
4328
public void test0521_try_finally() {
4329
	this.runConformTest(
4330
		new String[] {
4331
			"X.java",
4332
			"public class X\n" + 
4333
			"{\n" + 
4334
			"  X m;\n" + 
4335
			"  public void foo() {\n" + 
4336
			"    for(int j = 0; j < 10; j++) {\n" + 
4337
			"      try {\n" + 
4338
			"        j++;\n" + 
4339
			"      } finally {\n" + 
4340
			"        X t = m;\n" + 
4341
			"        if( t != null && t.bar()) {\n" + 
4342
			"        }\n" + 
4343
			"      }\n" + 
4344
			"    }\n" + 
4345
			"  }\n" + 
4346
			"  boolean bar() {\n" + 
4347
			"    return false;\n" + 
4348
			"  }\n" + 
4349
			"}"},
4350
		"");
4351
}
4352
4353
//null analysis -- try/finally
4354
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=149665
4355
//variant
4356
public void test0522_try_finally() {
4357
	this.runNegativeTest(
4358
		new String[] {
4359
			"X.java",
4360
			"public class X\n" + 
4361
			"{\n" + 
4362
			"  X m;\n" + 
4363
			"  public void foo() {\n" + 
4364
			"    for(int j = 0; j < 10; j++) {\n" + 
4365
			"      try {\n" + 
4366
			"        j++;\n" + 
4367
			"      } finally {\n" + 
4368
			"        X t = null;\n" + 
4369
			"        if(t.bar()) {\n" + 
4370
			"        }\n" + 
4371
			"      }\n" + 
4372
			"    }\n" + 
4373
			"  }\n" + 
4374
			"  boolean bar() {\n" + 
4375
			"    return false;\n" + 
4376
			"  }\n" + 
4377
			"}"},
4378
		"----------\n" + 
4379
		"1. ERROR in X.java (at line 10)\n" + 
4380
		"	if(t.bar()) {\n" + 
4381
		"	   ^\n" + 
4382
		"The variable t can only be null; it was either set to null or checked for null when last used\n" + 
4383
		"----------\n");
4384
}
4385
4386
// null analysis -- try/finally
4387
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=149665
4388
// variant
4389
public void test0523_try_finally() {
4390
	this.runNegativeTest(
4391
		new String[] {
4392
			"X.java",
4393
			"public class X\n" + 
4394
			"{\n" + 
4395
			"  X m;\n" + 
4396
			"  public void foo() {\n" + 
4397
			"    for(int j = 0; j < 10; j++) {\n" + 
4398
			"      try {\n" + 
4399
			"        j++;\n" + 
4400
			"      } finally {\n" + 
4401
			"        X t = m;\n" + 
4402
			"        if(t == null ? false : (t == null ? false : t.bar())) {\n" + 
4403
			"        }\n" + 
4404
			"      }\n" + 
4405
			"    }\n" + 
4406
			"  }\n" + 
4407
			"  boolean bar() {\n" + 
4408
			"    return false;\n" + 
4409
			"  }\n" + 
4410
			"}"},
4411
		"----------\n" + 
4412
		"1. ERROR in X.java (at line 10)\n" + 
4413
		"	if(t == null ? false : (t == null ? false : t.bar())) {\n" + 
4414
		"	                        ^\n" + 
4415
		"The variable t cannot be null; it was either set to a non-null value or assumed to be non-null when last used\n" + 
4416
		"----------\n");
4417
}
4418
4419
// null analysis -- try/finally
4420
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=149665
4421
// variant
4422
public void test0524_try_finally() {
4423
	this.runNegativeTest(
4424
		new String[] {
4425
			"X.java",
4426
			"public class X\n" + 
4427
			"{\n" + 
4428
			"  X m;\n" + 
4429
			"  public void foo() {\n" + 
4430
			"    for(int j = 0; j < 10; j++) {\n" + 
4431
			"      try {\n" + 
4432
			"        j++;\n" + 
4433
			"      } finally {\n" + 
4434
			"        X t = m;\n" + 
4435
			"        if(t != null ? false : (t == null ? false : t.bar())) {\n" + 
4436
			"        }\n" + 
4437
			"      }\n" + 
4438
			"    }\n" + 
4439
			"  }\n" + 
4440
			"  boolean bar() {\n" + 
4441
			"    return false;\n" + 
4442
			"  }\n" + 
4443
			"}"},
4444
		"----------\n" + 
4445
		"1. ERROR in X.java (at line 10)\n" + 
4446
		"	if(t != null ? false : (t == null ? false : t.bar())) {\n" + 
4447
		"	                        ^\n" + 
4448
		"The variable t can only be null; it was either set to null or checked for null when last used\n" + 
4449
		"----------\n");
4450
}
4451
4325
// null analysis -- try/catch
4452
// null analysis -- try/catch
4326
public void test0550_try_catch() {
4453
public void test0550_try_catch() {
4327
	this.runConformTest(
4454
	this.runConformTest(
(-)compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java (+22 lines)
Lines 62-67 Link Here
62
		// if (initsWhenTrue.equals(initsWhenFalse)) return initsWhenTrue; -- could optimize if #equals is defined
62
		// if (initsWhenTrue.equals(initsWhenFalse)) return initsWhenTrue; -- could optimize if #equals is defined
63
		return new ConditionalFlowInfo(initsWhenTrue, initsWhenFalse);
63
		return new ConditionalFlowInfo(initsWhenTrue, initsWhenFalse);
64
	}
64
	}
65
	
66
/**
67
 * Check whether a given local variable is known to be non null, either because 
68
 * it is definitely non null, or because is has been tested against non null.
69
 * @param local the variable to ckeck
70
 * @return true iff local cannot be null for this flow info
71
 */
72
// WORK (maxime) implement fast version for UnconditionalFlowInfo
73
public boolean cannotBeNull(LocalVariableBinding local) {
74
	return isDefinitelyNonNull(local) || isProtectedNonNull(local);
75
}
76
77
/**
78
 * Check whether a given local variable is known to be null, either because it
79
 * is definitely null, or because is has been tested against null.
80
 * @param local the variable to ckeck
81
 * @return true iff local can only be null for this flow info
82
 */
83
// WORK (maxime) implement fast version for UnconditionalFlowInfo
84
public boolean canOnlyBeNull(LocalVariableBinding local) {
85
	return isDefinitelyNull(local) || isProtectedNull(local);
86
}
65
87
66
/**
88
/**
67
 * Return a deep copy of the current instance.
89
 * Return a deep copy of the current instance.
(-)compiler/org/eclipse/jdt/internal/compiler/flow/FinallyFlowContext.java (-5 / +5 lines)
Lines 91-97 Link Here
91
						if (nullCheckTypes[i] == CAN_ONLY_NULL_NON_NULL) {
91
						if (nullCheckTypes[i] == CAN_ONLY_NULL_NON_NULL) {
92
							scope.problemReporter().localVariableCannotBeNull(local, expression);
92
							scope.problemReporter().localVariableCannotBeNull(local, expression);
93
						}
93
						}
94
						return;
94
						return; // WORK wrong, test second variable!
95
					}
95
					}
96
					if (flowInfo.isProtectedNull(local)) {
96
					if (flowInfo.isProtectedNull(local)) {
97
						scope.problemReporter().localVariableCanOnlyBeNull(local, expression);
97
						scope.problemReporter().localVariableCanOnlyBeNull(local, expression);
Lines 193-214 Link Here
193
			switch (checkType) {
193
			switch (checkType) {
194
				case CAN_ONLY_NULL_NON_NULL :
194
				case CAN_ONLY_NULL_NON_NULL :
195
				case CAN_ONLY_NULL:
195
				case CAN_ONLY_NULL:
196
					if (flowInfo.isProtectedNonNull(local)) {
196
					if (flowInfo.cannotBeNull(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
						}
199
						}
200
						return;
200
						return;
201
					}
201
					}
202
					if (flowInfo.isProtectedNull(local)) {
202
					if (flowInfo.canOnlyBeNull(local)) {
203
						scope.problemReporter().localVariableCanOnlyBeNull(local, reference);
203
						scope.problemReporter().localVariableCanOnlyBeNull(local, reference);
204
						return;
204
						return;
205
					}
205
					}
206
					break;
206
					break;
207
				case MAY_NULL :
207
				case MAY_NULL :
208
					if (flowInfo.isProtectedNonNull(local)) {
208
					if (flowInfo.cannotBeNull(local)) {
209
						return;
209
						return;
210
					}
210
					}
211
					if (flowInfo.isProtectedNull(local)) {
211
					if (flowInfo.canOnlyBeNull(local)) {
212
						scope.problemReporter().localVariableCanOnlyBeNull(local, reference);
212
						scope.problemReporter().localVariableCanOnlyBeNull(local, reference);
213
						return;
213
						return;
214
					}
214
					}

Return to bug 149665