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

Collapse All | Expand All

(-)a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java (-1 / +153 lines)
Lines 52-58 Link Here
52
// Static initializer to specify tests subset using TESTS_* static variables
52
// Static initializer to specify tests subset using TESTS_* static variables
53
// All specified tests which do not belong to the class are skipped...
53
// All specified tests which do not belong to the class are skipped...
54
static {
54
static {
55
//		TESTS_NAMES = new String[] { "test_assignment_expression_1" };
55
//		TESTS_NAMES = new String[] { "test_nonnull_parameter_015" };
56
//		TESTS_NUMBERS = new int[] { 561 };
56
//		TESTS_NUMBERS = new int[] { 561 };
57
//		TESTS_RANGE = new int[] { 1, 2049 };
57
//		TESTS_RANGE = new int[] { 1, 2049 };
58
}
58
}
Lines 550-555 Link Here
550
		"Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + 
550
		"Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + 
551
		"----------\n");
551
		"----------\n");
552
}
552
}
553
// non-null varargs (message send)
554
public void test_nonnull_parameter_015() {
555
	runNegativeTest(
556
		new String[] {
557
			"X.java",
558
			"import org.eclipse.jdt.annotation.*;\n" +
559
			"public class X {\n" +
560
			"    void foo(@NonNull Object ... o) {\n" +
561
			"        if (o != null)\n" +
562
			"              System.out.print(o.toString());\n" +
563
			"    }\n" +
564
			"    void foo2(int i, @NonNull Object ... o) {\n" +
565
			"        if (o.length > 0 && o[0] != null)\n" +
566
			"              System.out.print(o[0].toString());\n" +
567
			"    }\n" +
568
			"    void bar() {\n" +
569
			"        foo((Object)null);\n" +
570
			"        foo(this, null);\n" +
571
			"        foo(null, this);\n" +
572
			"        foo2(2, (Object)null);\n" +
573
			"        foo2(2, this, null);\n" +
574
			"        foo2(2, null, this);\n" +
575
			"        foo2(2, (Object[])null);\n" +
576
			"    }\n" +
577
			"}\n"},
578
			"----------\n" + 
579
			"1. ERROR in X.java (at line 4)\n" + 
580
			"	if (o != null)\n" + 
581
			"	    ^\n" + 
582
			"Redundant null check: The variable o cannot be null at this location\n" +
583
// cannot yet look into arrays:
584
//			"----------\n" + 
585
//			"2. ERROR in X.java (at line 8)\n" + 
586
//			"	if (o.length > 0 && o[0] != null)\n" + 
587
//			"	                    ^^^^\n" + 
588
//			"Redundant null check: The array variable o cannot contain null at this program location\n" + 
589
			"----------\n" + 
590
			"2. ERROR in X.java (at line 12)\n" + 
591
			"	foo((Object)null);\n" + 
592
			"	    ^^^^^^^^^^^^\n" + 
593
			"Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + 
594
			"----------\n" + 
595
			"3. ERROR in X.java (at line 13)\n" + 
596
			"	foo(this, null);\n" + 
597
			"	          ^^^^\n" + 
598
			"Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + 
599
			"----------\n" + 
600
			"4. ERROR in X.java (at line 14)\n" + 
601
			"	foo(null, this);\n" + 
602
			"	    ^^^^\n" + 
603
			"Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + 
604
			"----------\n" + 
605
			"5. ERROR in X.java (at line 15)\n" + 
606
			"	foo2(2, (Object)null);\n" + 
607
			"	        ^^^^^^^^^^^^\n" + 
608
			"Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + 
609
			"----------\n" + 
610
			"6. ERROR in X.java (at line 16)\n" + 
611
			"	foo2(2, this, null);\n" + 
612
			"	              ^^^^\n" + 
613
			"Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + 
614
			"----------\n" + 
615
			"7. ERROR in X.java (at line 17)\n" + 
616
			"	foo2(2, null, this);\n" + 
617
			"	        ^^^^\n" + 
618
			"Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + 
619
			"----------\n" + 
620
			"8. ERROR in X.java (at line 18)\n" + 
621
			"	foo2(2, (Object[])null);\n" + 
622
			"	        ^^^^^^^^^^^^^^\n" + 
623
			"Type mismatch: required \'@NonNull Object[]\' but the provided value is null\n" + 
624
			"----------\n",
625
		this.LIBS,
626
		true /* shouldFlush*/);
627
}
628
// non-null varargs (allocation and explicit constructor calls)
629
public void test_nonnull_parameter_016() {
630
	runNegativeTest(
631
		new String[] {
632
			"X.java",
633
			"import org.eclipse.jdt.annotation.*;\n" +
634
			"public class X {\n" +
635
			"    X(@NonNull Object ... o) {\n" +
636
			"        if (o != null)\n" +
637
			"              System.out.print(o.toString());\n" +
638
			"    }\n" +
639
			"    class Y extends X {\n" +
640
			"        Y(int i, @NonNull Object ... o) {\n" +
641
			"        	super(i, (Object)null);\n" +
642
			"        }\n" +
643
			"        Y(char c, @NonNull Object ... o) {\n" +
644
			"        	this(1, new Object(), null);\n" +
645
			"        }\n" +
646
			"    }\n" +
647
			"    void bar() {\n" +
648
			"        new X((Object)null);\n" +
649
			"        new X(this, null);\n" +
650
			"        X x = new X(null, this);\n" +
651
			"        x.new Y(2, (Object)null);\n" +
652
			"        this.new Y(2, null, this);\n" +
653
			"        this.new Y(2, (Object[])null);\n" +
654
			"    }\n" +
655
			"}\n"},
656
			"----------\n" + 
657
			"1. ERROR in X.java (at line 4)\n" + 
658
			"	if (o != null)\n" + 
659
			"	    ^\n" + 
660
			"Redundant null check: The variable o cannot be null at this location\n" + 
661
			"----------\n" + 
662
			"2. ERROR in X.java (at line 9)\n" + 
663
			"	super(i, (Object)null);\n" + 
664
			"	         ^^^^^^^^^^^^\n" + 
665
			"Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + 
666
			"----------\n" + 
667
			"3. ERROR in X.java (at line 12)\n" + 
668
			"	this(1, new Object(), null);\n" + 
669
			"	                      ^^^^\n" + 
670
			"Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + 
671
			"----------\n" + 
672
			"4. ERROR in X.java (at line 16)\n" + 
673
			"	new X((Object)null);\n" + 
674
			"	      ^^^^^^^^^^^^\n" + 
675
			"Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + 
676
			"----------\n" + 
677
			"5. ERROR in X.java (at line 17)\n" + 
678
			"	new X(this, null);\n" + 
679
			"	            ^^^^\n" + 
680
			"Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + 
681
			"----------\n" + 
682
			"6. ERROR in X.java (at line 18)\n" + 
683
			"	X x = new X(null, this);\n" + 
684
			"	            ^^^^\n" + 
685
			"Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + 
686
			"----------\n" + 
687
			"7. ERROR in X.java (at line 19)\n" + 
688
			"	x.new Y(2, (Object)null);\n" + 
689
			"	           ^^^^^^^^^^^^\n" + 
690
			"Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + 
691
			"----------\n" + 
692
			"8. ERROR in X.java (at line 20)\n" + 
693
			"	this.new Y(2, null, this);\n" + 
694
			"	              ^^^^\n" + 
695
			"Type mismatch: required \'@NonNull Object\' but the provided value is null\n" + 
696
			"----------\n" + 
697
			"9. ERROR in X.java (at line 21)\n" + 
698
			"	this.new Y(2, (Object[])null);\n" + 
699
			"	              ^^^^^^^^^^^^^^\n" + 
700
			"Type mismatch: required \'@NonNull Object[]\' but the provided value is null\n" + 
701
			"----------\n",
702
		this.LIBS,
703
		true /* shouldFlush*/);
704
}
553
// assigning potential null to a nonnull local variable
705
// assigning potential null to a nonnull local variable
554
public void test_nonnull_local_001() {
706
public void test_nonnull_local_001() {
555
	runNegativeTest(
707
	runNegativeTest(
(-)a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java (-1 / +33 lines)
Lines 64-70 Link Here
64
{
64
{
65
	// compare actual null-status against parameter annotations of the called method:
65
	// compare actual null-status against parameter annotations of the called method:
66
	if (arguments != null && methodBinding.parameterNonNullness != null) {
66
	if (arguments != null && methodBinding.parameterNonNullness != null) {
67
		for (int i = 0; i < arguments.length; i++) {
67
68
		// check if varargs need special treatment:
69
		int regularParamsLen = methodBinding.parameters.length;
70
		boolean passThrough = false;
71
		if (methodBinding.isVarargs()) {
72
			// this if-block essentially copied from generateArguments(..):
73
			if (regularParamsLen == arguments.length) {
74
				TypeBinding varArgsType = methodBinding.parameters[regularParamsLen-1];
75
				TypeBinding lastType = arguments[regularParamsLen-1].resolvedType;
76
				if (lastType == TypeBinding.NULL
77
						|| (varArgsType.dimensions() == lastType.dimensions()
78
						&& lastType.isCompatibleWith(varArgsType)))
79
					passThrough = true; // pass directly as-is
80
			}
81
			if (!passThrough)
82
				regularParamsLen--; // last one is treated specially
83
		}
84
85
		// main checking loop:
86
		for (int i = 0; i < regularParamsLen; i++) {
68
			if (methodBinding.parameterNonNullness[i] == Boolean.TRUE) {
87
			if (methodBinding.parameterNonNullness[i] == Boolean.TRUE) {
69
				TypeBinding expectedType = methodBinding.parameters[i];
88
				TypeBinding expectedType = methodBinding.parameters[i];
70
				Expression argument = arguments[i];
89
				Expression argument = arguments[i];
Lines 73-78 Link Here
73
					flowContext.recordNullityMismatch(currentScope, argument, nullStatus, expectedType);
92
					flowContext.recordNullityMismatch(currentScope, argument, nullStatus, expectedType);
74
			}
93
			}
75
		}
94
		}
95
96
		// if vararg is specified @NonNull:
97
		if (!passThrough && methodBinding.isVarargs() && methodBinding.parameterNonNullness[regularParamsLen] == Boolean.TRUE) {
98
			TypeBinding varArgsType = ((ArrayBinding)methodBinding.parameters[regularParamsLen]).elementsType(); // last type is array by definition
99
			// continue loop until all arguments are handled:
100
			int argumentsLen = arguments.length;
101
			for (int i=regularParamsLen; i<argumentsLen; i++) {
102
				Expression argument = arguments[i];
103
				int nullStatus = argument.nullStatus(flowInfo); // slight loss of precision: should also use the null info from the receiver.
104
				if (nullStatus != FlowInfo.NON_NULL) // if required non-null is not provided
105
					flowContext.recordNullityMismatch(currentScope, argument, nullStatus, varArgsType);				
106
			}
107
		}
76
	}
108
	}
77
}
109
}
78
110

Return to bug 365387