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

Collapse All | Expand All

(-)compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java (+6 lines)
Lines 55-60 Link Here
55
			case FlowInfo.NON_NULL :
55
			case FlowInfo.NON_NULL :
56
				flowInfo.markAsDefinitelyNonNull(local);
56
				flowInfo.markAsDefinitelyNonNull(local);
57
				break;
57
				break;
58
			case FlowInfo.POTENTIALLY_NULL :
59
				flowInfo.markAsPotentiallyNull(local);
60
				break;
58
			default:
61
			default:
59
				flowInfo.markAsDefinitelyUnknown(local);
62
				flowInfo.markAsDefinitelyUnknown(local);
60
		}
63
		}
Lines 66-71 Link Here
66
				case FlowInfo.NON_NULL :
69
				case FlowInfo.NON_NULL :
67
					flowContext.initsOnFinally.markAsDefinitelyNonNull(local);
70
					flowContext.initsOnFinally.markAsDefinitelyNonNull(local);
68
					break;
71
					break;
72
				case FlowInfo.POTENTIALLY_NULL :
73
					flowContext.initsOnFinally.markAsPotentiallyNull(local);
74
					break;
69
				default:
75
				default:
70
					flowContext.initsOnFinally.markAsDefinitelyUnknown(local);
76
					flowContext.initsOnFinally.markAsDefinitelyUnknown(local);
71
			}
77
			}
(-)compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java (-4 / +6 lines)
Lines 829-839 Link Here
829
	this.bits |= ASTNode.IsNonNull;
829
	this.bits |= ASTNode.IsNonNull;
830
}
830
}
831
831
832
	public int nullStatus(FlowInfo flowInfo) {
832
public int nullStatus(FlowInfo flowInfo) {
833
833
834
		if (/* (this.bits & IsNonNull) != 0 || */
834
	if (/* (this.bits & IsNonNull) != 0 || */
835
			this.constant != null && this.constant != Constant.NotAConstant)
835
		this.constant != null && this.constant != Constant.NotAConstant)
836
		return FlowInfo.NON_NULL; // constant expression cannot be null
836
	return FlowInfo.NON_NULL; // constant expression cannot be null
837
837
838
	LocalVariableBinding local = localVariableBinding();
838
	LocalVariableBinding local = localVariableBinding();
839
	if (local != null) {
839
	if (local != null) {
Lines 841-846 Link Here
841
			return FlowInfo.NULL;
841
			return FlowInfo.NULL;
842
		if (flowInfo.isDefinitelyNonNull(local))
842
		if (flowInfo.isDefinitelyNonNull(local))
843
			return FlowInfo.NON_NULL;
843
			return FlowInfo.NON_NULL;
844
		if (flowInfo.isPotentiallyNull(local))
845
			return FlowInfo.POTENTIALLY_NULL;
844
		return FlowInfo.UNKNOWN;
846
		return FlowInfo.UNKNOWN;
845
	}
847
	}
846
	return FlowInfo.NON_NULL;
848
	return FlowInfo.NON_NULL;
(-)compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java (+3 lines)
Lines 59-64 Link Here
59
			case FlowInfo.NON_NULL :
59
			case FlowInfo.NON_NULL :
60
				flowInfo.markAsDefinitelyNonNull(this.binding);
60
				flowInfo.markAsDefinitelyNonNull(this.binding);
61
				break;
61
				break;
62
			case FlowInfo.POTENTIALLY_NULL :
63
				flowInfo.markAsPotentiallyNull(this.binding);
64
				break;
62
			default:
65
			default:
63
				flowInfo.markAsDefinitelyUnknown(this.binding);
66
				flowInfo.markAsDefinitelyUnknown(this.binding);
64
		}
67
		}
(-)compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java (+2 lines)
Lines 774-779 Link Here
774
					return FlowInfo.NULL;
774
					return FlowInfo.NULL;
775
				if (flowInfo.isDefinitelyNonNull(local))
775
				if (flowInfo.isDefinitelyNonNull(local))
776
					return FlowInfo.NON_NULL;
776
					return FlowInfo.NON_NULL;
777
				if (flowInfo.isPotentiallyNull(local))
778
					return FlowInfo.POTENTIALLY_NULL;
777
				return FlowInfo.UNKNOWN;
779
				return FlowInfo.UNKNOWN;
778
			}
780
			}
779
	}
781
	}
(-)compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java (+3 lines)
Lines 23-28 Link Here
23
	public final static int UNKNOWN = 0;
23
	public final static int UNKNOWN = 0;
24
	public final static int NULL = 1;
24
	public final static int NULL = 1;
25
	public final static int NON_NULL = -1;
25
	public final static int NON_NULL = -1;
26
	public final static int POTENTIALLY_NULL = 2;
26
27
27
	public static final UnconditionalFlowInfo DEAD_END; // Represents a dead branch status of initialization
28
	public static final UnconditionalFlowInfo DEAD_END; // Represents a dead branch status of initialization
28
	static {
29
	static {
Lines 244-249 Link Here
244
	 * Record a local got definitely assigned to null.
245
	 * Record a local got definitely assigned to null.
245
	 */
246
	 */
246
	abstract public void markAsDefinitelyNull(LocalVariableBinding local);
247
	abstract public void markAsDefinitelyNull(LocalVariableBinding local);
248
	
249
	public void markAsPotentiallyNull(LocalVariableBinding local) { /* empty default impl. */ }
247
250
248
	/**
251
	/**
249
	 * Record a local got definitely assigned.
252
	 * Record a local got definitely assigned.
(-)compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java (+24 lines)
Lines 1284-1289 Link Here
1284
	}
1284
	}
1285
}
1285
}
1286
1286
1287
public void markAsPotentiallyNull(LocalVariableBinding local) {
1288
	if (this != DEAD_END) {
1289
		this.tagBits |= NULL_FLAG_MASK;
1290
        int position;
1291
        long mask;
1292
        if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
1293
            // use bits
1294
            this.nullBit1 &= ~(mask = 1L << position);
1295
            this.nullBit2 |= mask;
1296
            this.nullBit3 &= ~mask;
1297
            this.nullBit4 &= ~mask;
1298
        } else {
1299
    		// use extra vector
1300
    		int vectorIndex ;
1301
    		this.extra[2][vectorIndex = (position / BitCacheSize) - 1]
1302
    		    &= ~(mask = 1L << (position % BitCacheSize));
1303
    		this.extra[3][vectorIndex] |= mask;
1304
    		this.extra[4][vectorIndex] &= (mask = ~mask);
1305
    		this.extra[5][vectorIndex] &= mask;
1306
    	}
1307
1308
	}
1309
}
1310
1287
/**
1311
/**
1288
 * Mark a local as having been assigned to an unknown value.
1312
 * Mark a local as having been assigned to an unknown value.
1289
 * @param local the local to mark
1313
 * @param local the local to mark
(-)src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java (+130 lines)
Lines 11662-11665 Link Here
11662
		"----------\n",
11662
		"----------\n",
11663
	    JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
11663
	    JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
11664
}
11664
}
11665
11666
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=292478 -  Report potentially null across variable assignment
11667
// LocalDeclaration
11668
public void testBug292478() {
11669
    this.runNegativeTest(
11670
            new String[] {
11671
                "X.java",
11672
                "public class X {\n" +
11673
                "  void foo(Object o) {\n" +
11674
                "    if (o != null) {/* */}\n" +
11675
                "    Object p = o;\n" +
11676
                "    p.toString();\n" + // complain here
11677
                "  }\n" +
11678
                "}"},
11679
            "----------\n" +
11680
            "1. ERROR in X.java (at line 5)\n" + 
11681
            "	p.toString();\n" + 
11682
            "	^\n" + 
11683
            "Potential null pointer access: The variable p may be null at this location\n" + 
11684
            "----------\n",
11685
            JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
11686
}
11687
11688
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=292478 -  Report potentially null across variable assignment
11689
// Assignment
11690
public void testBug292478a() {
11691
  this.runNegativeTest(
11692
          new String[] {
11693
              "X.java",
11694
              "public class X {\n" +
11695
              "  void foo(Object o) {\n" +
11696
              "    Object p;" +
11697
              "    if (o != null) {/* */}\n" +
11698
              "    p = o;\n" +
11699
              "    p.toString();\n" + // complain here
11700
              "  }\n" +
11701
              "}"},
11702
          "----------\n" +
11703
          "1. ERROR in X.java (at line 5)\n" + 
11704
          "	p.toString();\n" + 
11705
          "	^\n" + 
11706
          "Potential null pointer access: The variable p may be null at this location\n" + 
11707
          "----------\n",
11708
          JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
11709
}
11710
11711
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=292478 -  Report potentially null across variable assignment
11712
//Assignment after definite null
11713
public void testBug292478b() {
11714
this.runNegativeTest(
11715
        new String[] {
11716
            "X.java",
11717
            "public class X {\n" +
11718
            "  void foo(Object o) {\n" +
11719
            "    Object p = null;\n" +
11720
            "    if (o != null) {/* */}\n" +
11721
            "    p = o;\n" +
11722
            "    p.toString();\n" + // complain here
11723
            "  }\n" +
11724
            "}"},
11725
        "----------\n" +
11726
        "1. ERROR in X.java (at line 6)\n" + 
11727
        "	p.toString();\n" + 
11728
        "	^\n" + 
11729
        "Potential null pointer access: The variable p may be null at this location\n" + 
11730
        "----------\n",
11731
        JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
11732
}
11733
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=292478 -  Report potentially null across variable assignment
11734
//Assignment after definite null - many locals
11735
public void testBug292478c() {
11736
this.runNegativeTest(
11737
      new String[] {
11738
          "X.java",
11739
          "public class X {\n" +
11740
          "  void foo(Object o) {\n" +
11741
          "    int i00, i01, i02, i03, i04, i05, i06, i07, i08, i09;\n" +
11742
          "    int i10, i11, i12, i13, i14, i15, i16, i17, i18, i19;\n" +
11743
          "    int i20, i21, i22, i23, i24, i25, i26, i27, i28, i29;\n" +
11744
          "    int i30, i31, i32, i33, i34, i35, i36, i37, i38, i39;\n" +
11745
          "    int i40, i41, i42, i43, i44, i45, i46, i47, i48, i49;\n" +
11746
          "    int i50, i51, i52, i53, i54, i55, i56, i57, i58, i59;\n" +
11747
          "    int i60, i61, i62, i63, i64, i65, i66, i67, i68, i69;\n" +
11748
          "    Object p = null;\n" +
11749
          "    if (o != null) {/* */}\n" +
11750
          "    p = o;\n" +
11751
          "    p.toString();\n" + // complain here
11752
          "  }\n" +
11753
          "}"},
11754
      "----------\n" +
11755
      "1. ERROR in X.java (at line 13)\n" + 
11756
      "	p.toString();\n" + 
11757
      "	^\n" + 
11758
      "Potential null pointer access: The variable p may be null at this location\n" + 
11759
      "----------\n",
11760
      JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
11761
}
11762
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=292478 -  Report potentially null across variable assignment
11763
//Assignment affects initsOnFinally
11764
public void testBug292478d() {
11765
	this.runNegativeTest(
11766
		new String[] {
11767
			"X.java",
11768
			"public class X {\n" +
11769
			" X bar() {\n" +
11770
			"   return null;\n" +
11771
			" }\n" +
11772
			" Object foo() {\n" +
11773
			"   X x = null;\n" +
11774
			"   X y = new X();\n" +
11775
			"   X u = null;\n" +
11776
			"   try {\n" +
11777
			"     u = bar();\n" +
11778
			"     x = bar();\n" +
11779
			"     if (x==null) { }\n" +
11780
			"     y = x;\n" +				// this makes y potentially null
11781
			"     if (x==null) { y=bar();} else { y=new X(); }\n" +
11782
			"     return x;\n" +
11783
			"   } finally {\n" +
11784
			"     y.toString();\n" +		// must complain against potentially null, although normal exist of tryBlock says differently (unknown or non-null)
11785
			"   }\n" +
11786
			" }\n" +
11787
			"}\n"},
11788
		"----------\n" + 
11789
		"1. ERROR in X.java (at line 17)\n" + 
11790
		"	y.toString();\n" + 
11791
		"	^\n" + 
11792
		"Potential null pointer access: The variable y may be null at this location\n" + 
11793
		"----------\n");
11794
}
11665
}
11795
}

Return to bug 292478