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

(-)src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTests.java (+11 lines)
Lines 648-657 Link Here
648
					isDefinitelyNonNull = state.isDefinitelyNonNull(TestLocalVariableBinding.local0),
648
					isDefinitelyNonNull = state.isDefinitelyNonNull(TestLocalVariableBinding.local0),
649
					isDefinitelyNull = state.isDefinitelyNull(TestLocalVariableBinding.local0),
649
					isDefinitelyNull = state.isDefinitelyNull(TestLocalVariableBinding.local0),
650
					isDefinitelyUnknown = state.isDefinitelyUnknown(TestLocalVariableBinding.local0),
650
					isDefinitelyUnknown = state.isDefinitelyUnknown(TestLocalVariableBinding.local0),
651
					isPotentiallyNonNull = state.isPotentiallyNonNull(TestLocalVariableBinding.local0),
651
					isPotentiallyNull = state.isPotentiallyNull(TestLocalVariableBinding.local0),
652
					isPotentiallyNull = state.isPotentiallyNull(TestLocalVariableBinding.local0),
652
					isPotentiallyUnknown = state.isPotentiallyUnknown(TestLocalVariableBinding.local0),
653
					isPotentiallyUnknown = state.isPotentiallyUnknown(TestLocalVariableBinding.local0),
653
					isProtectedNonNull = state.isProtectedNonNull(TestLocalVariableBinding.local0),
654
					isProtectedNonNull = state.isProtectedNonNull(TestLocalVariableBinding.local0),
654
					isProtectedNull = state.isProtectedNull(TestLocalVariableBinding.local0),
655
					isProtectedNull = state.isProtectedNull(TestLocalVariableBinding.local0),
656
					cannotBeDefinitelyNullOrNonNull = state.cannotBeDefinitelyNullOrNonNull(TestLocalVariableBinding.local0),
655
					cannotBeNull = state.cannotBeNull(TestLocalVariableBinding.local0),
657
					cannotBeNull = state.cannotBeNull(TestLocalVariableBinding.local0),
656
					canOnlyBeNull = state.canOnlyBeNull(TestLocalVariableBinding.local0);
658
					canOnlyBeNull = state.canOnlyBeNull(TestLocalVariableBinding.local0);
657
				if (isDefinitelyNonNull
659
				if (isDefinitelyNonNull
Lines 691-696 Link Here
691
									|| isDefinitelyUnknown || isPotentiallyNull
693
									|| isDefinitelyUnknown || isPotentiallyNull
692
									|| isPotentiallyUnknown || isProtectedNonNull
694
									|| isPotentiallyUnknown || isProtectedNonNull
693
									|| isProtectedNull)
695
									|| isProtectedNull)
696
						|| cannotBeDefinitelyNullOrNonNull != 
697
							(isPotentiallyUnknown ||
698
								isPotentiallyNull && isPotentiallyNonNull)
694
						|| cannotBeNull != (isProtectedNonNull || 
699
						|| cannotBeNull != (isProtectedNonNull || 
695
								isDefinitelyNonNull)
700
								isDefinitelyNonNull)
696
						|| canOnlyBeNull != (isProtectedNull || 
701
						|| canOnlyBeNull != (isProtectedNull || 
Lines 717-726 Link Here
717
				isDefinitelyNonNull = state.isDefinitelyNonNull(TestLocalVariableBinding.local64),
722
				isDefinitelyNonNull = state.isDefinitelyNonNull(TestLocalVariableBinding.local64),
718
				isDefinitelyNull = state.isDefinitelyNull(TestLocalVariableBinding.local64),
723
				isDefinitelyNull = state.isDefinitelyNull(TestLocalVariableBinding.local64),
719
				isDefinitelyUnknown = state.isDefinitelyUnknown(TestLocalVariableBinding.local64),
724
				isDefinitelyUnknown = state.isDefinitelyUnknown(TestLocalVariableBinding.local64),
725
				isPotentiallyNonNull = state.isPotentiallyNonNull(TestLocalVariableBinding.local64),
720
				isPotentiallyNull = state.isPotentiallyNull(TestLocalVariableBinding.local64),
726
				isPotentiallyNull = state.isPotentiallyNull(TestLocalVariableBinding.local64),
721
				isPotentiallyUnknown = state.isPotentiallyUnknown(TestLocalVariableBinding.local64),
727
				isPotentiallyUnknown = state.isPotentiallyUnknown(TestLocalVariableBinding.local64),
722
				isProtectedNonNull = state.isProtectedNonNull(TestLocalVariableBinding.local64),
728
				isProtectedNonNull = state.isProtectedNonNull(TestLocalVariableBinding.local64),
723
				isProtectedNull = state.isProtectedNull(TestLocalVariableBinding.local64),
729
				isProtectedNull = state.isProtectedNull(TestLocalVariableBinding.local64),
730
				cannotBeDefinitelyNullOrNonNull = state.cannotBeDefinitelyNullOrNonNull(TestLocalVariableBinding.local64),
724
				cannotBeNull = state.cannotBeNull(TestLocalVariableBinding.local64),
731
				cannotBeNull = state.cannotBeNull(TestLocalVariableBinding.local64),
725
				canOnlyBeNull = state.canOnlyBeNull(TestLocalVariableBinding.local64);
732
				canOnlyBeNull = state.canOnlyBeNull(TestLocalVariableBinding.local64);
726
				if (isDefinitelyNonNull
733
				if (isDefinitelyNonNull
Lines 760-765 Link Here
760
									|| isDefinitelyUnknown || isPotentiallyNull
767
									|| isDefinitelyUnknown || isPotentiallyNull
761
									|| isPotentiallyUnknown || isProtectedNonNull
768
									|| isPotentiallyUnknown || isProtectedNonNull
762
									|| isProtectedNull)
769
									|| isProtectedNull)
770
									|| cannotBeDefinitelyNullOrNonNull != 
771
										(isPotentiallyUnknown ||
772
											isPotentiallyNull && 
773
												isPotentiallyNonNull)
763
									|| cannotBeNull != (isProtectedNonNull || 
774
									|| cannotBeNull != (isProtectedNonNull || 
764
											isDefinitelyNonNull)
775
											isDefinitelyNonNull)
765
									|| canOnlyBeNull != (isProtectedNull || 
776
									|| canOnlyBeNull != (isProtectedNull || 
(-)src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java (+29 lines)
Lines 3759-3764 Link Here
3759
		"");
3759
		"");
3760
} 
3760
} 
3761
3761
3762
// null analysis - while
3763
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=154995
3764
public void test0457_while_nested_break() {
3765
	this.runConformTest(
3766
		new String[] {
3767
			"X.java",
3768
			"public class X {\n" + 
3769
			"  public void test(String p, String q, boolean b) {\n" + 
3770
			"    while (b) {\n" + 
3771
			"      String e = q;\n" + 
3772
			"      e.trim();\n" + 
3773
			"      while (true) {\n" + 
3774
			"        if (b)\n" + 
3775
			"          e = q;\n" + 
3776
			"        else\n" + 
3777
			"          e = null;\n" + 
3778
			"        if (e == null || p != null) {\n" + 
3779
			"          if (e != null) {\n" + // should not complain here
3780
			"            // Do something\n" + 
3781
			"          }\n" + 
3782
			"          break;\n" + 
3783
			"        }\n" + 
3784
			"      }\n" + 
3785
			"    }\n" + 
3786
			"  }\n" + 
3787
			"}"},
3788
		"");
3789
} 
3790
3762
// null analysis -- try/finally
3791
// null analysis -- try/finally
3763
public void test0500_try_finally() {
3792
public void test0500_try_finally() {
3764
	this.runConformTest(
3793
	this.runConformTest(
(-)compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java (+31 lines)
Lines 470-475 Link Here
470
	return this;
470
	return this;
471
}
471
}
472
472
473
final public boolean cannotBeDefinitelyNullOrNonNull(LocalVariableBinding local) {
474
	if ((this.tagBits & NULL_FLAG_MASK) == 0 || 
475
			(local.type.tagBits & TagBits.IsBaseType) != 0) {
476
		return false;
477
	}
478
	int position;
479
	if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
480
		// use bits
481
		return (
482
			(~this.nullBit1 
483
					& (this.nullBit2 & this.nullBit3 | this.nullBit4)
484
				| ~this.nullBit2 & ~this.nullBit3 & this.nullBit4)
485
			& (1L << position)) != 0;
486
	}
487
	// use extra vector
488
	if (this.extra == null) {
489
		return false; // if vector not yet allocated, then not initialized
490
	}
491
	int vectorIndex;
492
	if ((vectorIndex = (position / BitCacheSize) - 1) >= 
493
			this.extra[0].length) {
494
		return false; // if not enough room in vector, then not initialized
495
	}
496
	long a2, a3, a4;
497
	return (
498
			(~this.extra[2][vectorIndex] 
499
					& ((a2 = this.extra[3][vectorIndex]) & (a3 = this.extra[4][vectorIndex]) | (a4 = this.extra[5][vectorIndex]))
500
				| ~a2 & ~a3 & a4)
501
		    & (1L << (position % BitCacheSize))) != 0;
502
}
503
473
final public boolean cannotBeNull(LocalVariableBinding local) {
504
final public boolean cannotBeNull(LocalVariableBinding local) {
474
	if ((this.tagBits & NULL_FLAG_MASK) == 0 || 
505
	if ((this.tagBits & NULL_FLAG_MASK) == 0 || 
475
			(local.type.tagBits & TagBits.IsBaseType) != 0) {
506
			(local.type.tagBits & TagBits.IsBaseType) != 0) {
(-)compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java (+16 lines)
Lines 64-69 Link Here
64
	}
64
	}
65
	
65
	
66
/**
66
/**
67
 * Check whether a given local variable is known to be unable to gain a definite
68
 * non null or definite null status by the use of an enclosing flow info. The
69
 * semantics are that if the current flow info marks the variable as potentially
70
 * unknown or else as being both potentially null and potentially non null,
71
 * then it won't ever be promoted as definitely null or definitely non null. (It
72
 * could still get promoted to definite unknown).
73
 * @param local the variable to ckeck
74
 * @return true iff this flow info prevents local from being promoted to 
75
 *         definite non null or definite null against an enclosing flow info
76
 */
77
public boolean cannotBeDefinitelyNullOrNonNull(LocalVariableBinding local) {
78
	return isPotentiallyUnknown(local) ||
79
		isPotentiallyNonNull(local) && isPotentiallyNull(local);
80
}
81
82
/**
67
 * Check whether a given local variable is known to be non null, either because 
83
 * 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.
84
 * it is definitely non null, or because is has been tested against non null.
69
 * @param local the variable to ckeck
85
 * @param local the variable to ckeck
(-)compiler/org/eclipse/jdt/internal/compiler/flow/LoopingFlowContext.java (-1 / +1 lines)
Lines 332-338 Link Here
332
				scope.problemReporter().localVariableCanOnlyBeNull(local, reference);
332
				scope.problemReporter().localVariableCanOnlyBeNull(local, reference);
333
				return;
333
				return;
334
			}
334
			}
335
			if (flowInfo.isPotentiallyUnknown(local)) {
335
			if (flowInfo.cannotBeDefinitelyNullOrNonNull(local)) {
336
				return;
336
				return;
337
			}
337
			}
338
			if (flowInfo.isPotentiallyNonNull(local)) {
338
			if (flowInfo.isPotentiallyNonNull(local)) {
(-)compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java (-2 / +2 lines)
Lines 503-509 Link Here
503
				scope.problemReporter().localVariableCannotBeNull(local, reference);				
503
				scope.problemReporter().localVariableCannotBeNull(local, reference);				
504
				return;
504
				return;
505
			}
505
			}
506
			else if (flowInfo.isPotentiallyUnknown(local)) {
506
			else if (flowInfo.cannotBeDefinitelyNullOrNonNull(local)) {
507
				return;
507
				return;
508
			}
508
			}
509
		case CAN_ONLY_NULL:
509
		case CAN_ONLY_NULL:
Lines 511-517 Link Here
511
				scope.problemReporter().localVariableCanOnlyBeNull(local, reference);
511
				scope.problemReporter().localVariableCanOnlyBeNull(local, reference);
512
				return;
512
				return;
513
			}
513
			}
514
			else if (flowInfo.isPotentiallyUnknown(local)) {
514
			else if (flowInfo.cannotBeDefinitelyNullOrNonNull(local)) {
515
				return;
515
				return;
516
			}
516
			}
517
			break;
517
			break;

Return to bug 154995