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

Collapse All | Expand All

(-)Eclipse Java Tests Compiler/org/eclipse/jdt/tests/compiler/regression/InitializationTest.java (-3 / +292 lines)
Lines 5921-5928 Link Here
5921
		"----------\n");
5921
		"----------\n");
5922
}
5922
}
5923
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=257716
5923
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=257716
5924
public void _test196() {
5924
public void test196() {
5925
	this.runNegativeTest(
5925
	this.runConformTest(
5926
		new String[] {
5926
		new String[] {
5927
			"X.java",
5927
			"X.java",
5928
			"public class X {\n" + 
5928
			"public class X {\n" + 
Lines 5933-5943 Link Here
5933
			"			int i = hello;\n" + 
5933
			"			int i = hello;\n" + 
5934
			"		};\n" + 
5934
			"		};\n" + 
5935
			"	}\n" + 
5935
			"	}\n" + 
5936
			"}\n"
5937
		},
5938
		"");
5939
}
5940
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=257716
5941
public void test197() {
5942
	this.runNegativeTest(
5943
		new String[] {
5944
			"X.java",
5945
			"public class X {\n" + 
5946
			"	final int hello;\n" + 
5936
			"	public X(int i) {\n" + 
5947
			"	public X(int i) {\n" + 
5937
			"		new Object() {\n" + 
5948
			"		new Object() {\n" + 
5938
			"			int j = hello;\n" + 
5949
			"			int j = hello;\n" + 
5939
			"		};\n" + 
5950
			"		};\n" + 
5940
			"	}\n" + 
5951
			"	}\n" + 
5952
			"}\n"
5953
		},
5954
		"----------\n" + 
5955
		"1. ERROR in X.java (at line 3)\n" + 
5956
		"	public X(int i) {\n" + 
5957
		"	       ^^^^^^^^\n" + 
5958
		"The blank final field hello may not have been initialized\n" + 
5959
		"----------\n" + 
5960
		"2. WARNING in X.java (at line 5)\n" + 
5961
		"	int j = hello;\n" + 
5962
		"	    ^\n" + 
5963
		"The field new Object(){}.j is never read locally\n" + 
5964
		"----------\n" + 
5965
		"3. ERROR in X.java (at line 5)\n" + 
5966
		"	int j = hello;\n" + 
5967
		"	        ^^^^^\n" + 
5968
		"The blank final field hello may not have been initialized\n" + 
5969
		"----------\n");
5970
}
5971
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=257716
5972
public void test198() {
5973
	this.runNegativeTest(
5974
		new String[] {
5975
			"X.java",
5976
			"public class X {\n" + 
5977
			"	final int hello;\n" + 
5941
			"	public X(long l) {\n" + 
5978
			"	public X(long l) {\n" + 
5942
			"		if (l > 0) {\n" + 
5979
			"		if (l > 0) {\n" + 
5943
			"			new Object() {\n" + 
5980
			"			new Object() {\n" + 
Lines 5947-5953 Link Here
5947
			"	}	\n" + 
5984
			"	}	\n" + 
5948
			"}\n"
5985
			"}\n"
5949
		},
5986
		},
5950
		"xx");
5987
		"----------\n" + 
5988
		"1. ERROR in X.java (at line 3)\n" + 
5989
		"	public X(long l) {\n" + 
5990
		"	       ^^^^^^^^^\n" + 
5991
		"The blank final field hello may not have been initialized\n" + 
5992
		"----------\n" + 
5993
		"2. WARNING in X.java (at line 6)\n" + 
5994
		"	int j = hello;\n" + 
5995
		"	    ^\n" + 
5996
		"The field new Object(){}.j is never read locally\n" + 
5997
		"----------\n" + 
5998
		"3. ERROR in X.java (at line 6)\n" + 
5999
		"	int j = hello;\n" + 
6000
		"	        ^^^^^\n" + 
6001
		"The blank final field hello may not have been initialized\n" + 
6002
		"----------\n");
6003
}
6004
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=257716 - variation
6005
public void test199() {
6006
	this.runNegativeTest(
6007
		new String[] {
6008
			"X.java",
6009
			"public class X {\n" + 
6010
			"	final int hello;\n" + 
6011
			"	public X() {\n" + 
6012
			"		hello = 0;\n" + 
6013
			"		new Object() {\n" + 
6014
			"			int i = X.this.hello;\n" + 
6015
			"		};\n" + 
6016
			"	}\n" + 
6017
			"	public X(int a) {\n" + 
6018
			"		new Object() {\n" + 
6019
			"			int j = X.this.hello;\n" + 
6020
			"		};\n" + 
6021
			"	}\n" + 			
6022
			"}\n"
6023
		},
6024
		"----------\n" + 
6025
		"1. WARNING in X.java (at line 6)\n" + 
6026
		"	int i = X.this.hello;\n" + 
6027
		"	    ^\n" + 
6028
		"The field new Object(){}.i is never read locally\n" + 
6029
		"----------\n" + 
6030
		"2. ERROR in X.java (at line 9)\n" + 
6031
		"	public X(int a) {\n" + 
6032
		"	       ^^^^^^^^\n" + 
6033
		"The blank final field hello may not have been initialized\n" + 
6034
		"----------\n" + 
6035
		"3. WARNING in X.java (at line 11)\n" + 
6036
		"	int j = X.this.hello;\n" + 
6037
		"	    ^\n" + 
6038
		"The field new Object(){}.j is never read locally\n" + 
6039
		"----------\n");
6040
}
6041
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=257716 - variation
6042
public void test200() {
6043
	this.runNegativeTest(
6044
		new String[] {
6045
			"X.java",
6046
			"public class X {\n" + 
6047
			"	final int hello;\n" + 
6048
			"	public X() {\n" + 
6049
			"		hello = 0;\n" + 
6050
			"		new Object() {\n" + 
6051
			"			X x = X.this;\n" + 
6052
			"			int i = x.hello;\n" + 
6053
			"		};\n" + 
6054
			"	}\n" + 
6055
			"	public X(int a) {\n" + 
6056
			"		new Object() {\n" + 
6057
			"			X x = X.this;\n" + 
6058
			"			int j = x.hello;\n" + 
6059
			"		};\n" + 
6060
			"	}\n" + 
6061
			"}\n"
6062
		},
6063
		"----------\n" + 
6064
		"1. WARNING in X.java (at line 7)\n" + 
6065
		"	int i = x.hello;\n" + 
6066
		"	    ^\n" + 
6067
		"The field new Object(){}.i is never read locally\n" + 
6068
		"----------\n" + 
6069
		"2. ERROR in X.java (at line 10)\n" + 
6070
		"	public X(int a) {\n" + 
6071
		"	       ^^^^^^^^\n" + 
6072
		"The blank final field hello may not have been initialized\n" + 
6073
		"----------\n" + 
6074
		"3. WARNING in X.java (at line 13)\n" + 
6075
		"	int j = x.hello;\n" + 
6076
		"	    ^\n" + 
6077
		"The field new Object(){}.j is never read locally\n" + 
6078
		"----------\n");
6079
}
6080
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=257716 - variation
6081
public void test201() {
6082
	this.runNegativeTest(
6083
		new String[] {
6084
			"X.java",
6085
			"public class X {\n" + 
6086
			"	final int hello;\n" + 
6087
			"	class M {\n" + 
6088
			"		public M() {\n" + 
6089
			"			hello = 0;\n" + 
6090
			"			new Object() {\n" + 
6091
			"				int i = hello;\n" + 
6092
			"			};\n" + 
6093
			"		}\n" + 
6094
			"		public M(int a) {\n" + 
6095
			"			new Object() {\n" + 
6096
			"				int j = hello;\n" + 
6097
			"			};\n" + 
6098
			"		}\n" + 
6099
			"	}\n" + 
6100
			"}\n"
6101
		},
6102
		"----------\n" + 
6103
		"1. ERROR in X.java (at line 1)\n" + 
6104
		"	public class X {\n" + 
6105
		"	             ^\n" + 
6106
		"The blank final field hello may not have been initialized\n" + 
6107
		"----------\n" + 
6108
		"2. ERROR in X.java (at line 5)\n" + 
6109
		"	hello = 0;\n" + 
6110
		"	^^^^^\n" + 
6111
		"The final field X.hello cannot be assigned\n" + 
6112
		"----------\n" + 
6113
		"3. WARNING in X.java (at line 7)\n" + 
6114
		"	int i = hello;\n" + 
6115
		"	    ^\n" + 
6116
		"The field new Object(){}.i is never read locally\n" + 
6117
		"----------\n" + 
6118
		"4. WARNING in X.java (at line 12)\n" + 
6119
		"	int j = hello;\n" + 
6120
		"	    ^\n" + 
6121
		"The field new Object(){}.j is never read locally\n" + 
6122
		"----------\n");
6123
}
6124
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=257716 - variation
6125
public void test202() {
6126
	this.runNegativeTest(
6127
		new String[] {
6128
			"X.java",
6129
			"public class X {\n" + 
6130
			"	final int hello;\n" + 
6131
			"	public X() {\n" + 
6132
			"		hello = 0;\n" + 
6133
			"		class Local {\n" + 
6134
			"			Object o = new Object() {\n" + 
6135
			"				int i = hello;\n" + 
6136
			"			};\n" + 
6137
			"		}\n" + 
6138
			"	}\n" + 
6139
			"	public X(int a) {\n" + 
6140
			"		class Local {\n" + 
6141
			"			Object o = new Object() {\n" + 
6142
			"				int j = hello;\n" + 
6143
			"			};\n" + 
6144
			"		}\n" + 
6145
			"	}\n" + 
6146
			"}\n"
6147
6148
		},
6149
		"----------\n" + 
6150
		"1. WARNING in X.java (at line 5)\n" + 
6151
		"	class Local {\n" + 
6152
		"	      ^^^^^\n" + 
6153
		"The type Local is never used locally\n" + 
6154
		"----------\n" + 
6155
		"2. WARNING in X.java (at line 6)\n" + 
6156
		"	Object o = new Object() {\n" + 
6157
		"	       ^\n" + 
6158
		"The field Local.o is never read locally\n" + 
6159
		"----------\n" + 
6160
		"3. WARNING in X.java (at line 7)\n" + 
6161
		"	int i = hello;\n" + 
6162
		"	    ^\n" + 
6163
		"The field new Object(){}.i is never read locally\n" + 
6164
		"----------\n" + 
6165
		"4. ERROR in X.java (at line 11)\n" + 
6166
		"	public X(int a) {\n" + 
6167
		"	       ^^^^^^^^\n" + 
6168
		"The blank final field hello may not have been initialized\n" + 
6169
		"----------\n" + 
6170
		"5. WARNING in X.java (at line 12)\n" + 
6171
		"	class Local {\n" + 
6172
		"	      ^^^^^\n" + 
6173
		"The type Local is never used locally\n" + 
6174
		"----------\n" + 
6175
		"6. WARNING in X.java (at line 13)\n" + 
6176
		"	Object o = new Object() {\n" + 
6177
		"	       ^\n" + 
6178
		"The field Local.o is never read locally\n" + 
6179
		"----------\n" + 
6180
		"7. WARNING in X.java (at line 14)\n" + 
6181
		"	int j = hello;\n" + 
6182
		"	    ^\n" + 
6183
		"The field new Object(){}.j is never read locally\n" + 
6184
		"----------\n");
6185
}
6186
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=257716 - variation
6187
public void test203() {
6188
	this.runNegativeTest(
6189
		new String[] {
6190
			"X.java",
6191
			"public class X {\n" + 
6192
			"	final int hello;\n" + 
6193
			"	public X() {\n" + 
6194
			"		hello = 0;\n" + 
6195
			"		new X() {\n" + 
6196
			"			final int world;\n" + 
6197
			"			{\n" + 
6198
			"				world = 0;\n" + 
6199
			"			}\n" + 
6200
			"			int i = new Object() {\n" + 
6201
			"				int j = hello + world; \n" + 
6202
			"			}.j;\n" + 
6203
			"		};\n" + 
6204
			"	}\n" + 
6205
			"	public X(int i) {\n" + 
6206
			"		new X() {\n" + 
6207
			"			final int world;\n" + 
6208
			"			{\n" + 
6209
			"				world = 0;\n" + 
6210
			"			}			\n" + 
6211
			"			int k = new Object() { \n" + 
6212
			"				int l = hello + world; \n" + 
6213
			"			}.l;\n" + 
6214
			"		};\n" + 
6215
			"	}\n" + 
6216
			"}\n"
6217
6218
		},
6219
		"----------\n" + 
6220
		"1. WARNING in X.java (at line 10)\n" + 
6221
		"	int i = new Object() {\n" + 
6222
		"	    ^\n" + 
6223
		"The field new X(){}.i is never read locally\n" + 
6224
		"----------\n" + 
6225
		"2. ERROR in X.java (at line 15)\n" + 
6226
		"	public X(int i) {\n" + 
6227
		"	       ^^^^^^^^\n" + 
6228
		"The blank final field hello may not have been initialized\n" + 
6229
		"----------\n" + 
6230
		"3. WARNING in X.java (at line 21)\n" + 
6231
		"	int k = new Object() { \n" + 
6232
		"	    ^\n" + 
6233
		"The field new X(){}.k is never read locally\n" + 
6234
		"----------\n" + 
6235
		"4. ERROR in X.java (at line 22)\n" + 
6236
		"	int l = hello + world; \n" + 
6237
		"	        ^^^^^\n" + 
6238
		"The blank final field hello may not have been initialized\n" + 
6239
		"----------\n");
5951
}
6240
}
5952
public static Class testClass() {
6241
public static Class testClass() {
5953
	return InitializationTest.class;
6242
	return InitializationTest.class;
(-)compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java (-9 / +4 lines)
Lines 616-623 Link Here
616
			this.scope.problemReporter().unusedPrivateType(this);
616
			this.scope.problemReporter().unusedPrivateType(this);
617
		}
617
		}
618
	}
618
	}
619
	InitializationFlowContext initializerContext = new InitializationFlowContext(null, this, this.initializerScope);
619
	InitializationFlowContext initializerContext = new InitializationFlowContext(null, this, flowInfo, flowContext, this.initializerScope);
620
	InitializationFlowContext staticInitializerContext = new InitializationFlowContext(null, this, this.staticInitializerScope);
620
	InitializationFlowContext staticInitializerContext = new InitializationFlowContext(null, this, flowInfo, flowContext, this.staticInitializerScope);
621
	FlowInfo nonStaticFieldInfo = flowInfo.unconditionalFieldLessCopy();
621
	FlowInfo nonStaticFieldInfo = flowInfo.unconditionalFieldLessCopy();
622
	FlowInfo staticFieldInfo = flowInfo.unconditionalFieldLessCopy();
622
	FlowInfo staticFieldInfo = flowInfo.unconditionalFieldLessCopy();
623
	if (this.fields != null) {
623
	if (this.fields != null) {
Lines 632-642 Link Here
632
				} else {*/
632
				} else {*/
633
				staticInitializerContext.handledExceptions = Binding.ANY_EXCEPTION; // tolerate them all, and record them
633
				staticInitializerContext.handledExceptions = Binding.ANY_EXCEPTION; // tolerate them all, and record them
634
				/*}*/
634
				/*}*/
635
				staticFieldInfo =
635
				staticFieldInfo = field.analyseCode(this.staticInitializerScope, staticInitializerContext, staticFieldInfo);
636
					field.analyseCode(
637
						this.staticInitializerScope,
638
						staticInitializerContext,
639
						staticFieldInfo);
640
				// in case the initializer is not reachable, use a reinitialized flowInfo and enter a fake reachable
636
				// in case the initializer is not reachable, use a reinitialized flowInfo and enter a fake reachable
641
				// branch, since the previous initializer already got the blame.
637
				// branch, since the previous initializer already got the blame.
642
				if (staticFieldInfo == FlowInfo.DEAD_END) {
638
				if (staticFieldInfo == FlowInfo.DEAD_END) {
Lines 652-659 Link Here
652
				} else {*/
648
				} else {*/
653
					initializerContext.handledExceptions = Binding.ANY_EXCEPTION; // tolerate them all, and record them
649
					initializerContext.handledExceptions = Binding.ANY_EXCEPTION; // tolerate them all, and record them
654
				/*}*/
650
				/*}*/
655
				nonStaticFieldInfo =
651
				nonStaticFieldInfo = field.analyseCode(this.initializerScope, initializerContext, nonStaticFieldInfo);
656
					field.analyseCode(this.initializerScope, initializerContext, nonStaticFieldInfo);
657
				// in case the initializer is not reachable, use a reinitialized flowInfo and enter a fake reachable
652
				// in case the initializer is not reachable, use a reinitialized flowInfo and enter a fake reachable
658
				// branch, since the previous initializer already got the blame.
653
				// branch, since the previous initializer already got the blame.
659
				if (nonStaticFieldInfo == FlowInfo.DEAD_END) {
654
				if (nonStaticFieldInfo == FlowInfo.DEAD_END) {
(-)compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java (+1 lines)
Lines 54-59 Link Here
54
					staticInitializerFlowContext.parent,
54
					staticInitializerFlowContext.parent,
55
					this,
55
					this,
56
					Binding.NO_EXCEPTIONS,
56
					Binding.NO_EXCEPTIONS,
57
					staticInitializerFlowContext,
57
					this.scope,
58
					this.scope,
58
					FlowInfo.DEAD_END);
59
					FlowInfo.DEAD_END);
59
60
(-)compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java (+2 lines)
Lines 87-92 Link Here
87
				flowContext,
87
				flowContext,
88
				this,
88
				this,
89
				this.caughtExceptionTypes,
89
				this.caughtExceptionTypes,
90
				null,
90
				this.scope,
91
				this.scope,
91
				flowInfo.unconditionalInits());
92
				flowInfo.unconditionalInits());
92
		handlingContext.initsOnFinally =
93
		handlingContext.initsOnFinally =
Lines 198-203 Link Here
198
				insideSubContext,
199
				insideSubContext,
199
				this,
200
				this,
200
				this.caughtExceptionTypes,
201
				this.caughtExceptionTypes,
202
				null,
201
				this.scope,
203
				this.scope,
202
				flowInfo.unconditionalInits());
204
				flowInfo.unconditionalInits());
203
		handlingContext.initsOnFinally =
205
		handlingContext.initsOnFinally =
(-)compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java (+1 lines)
Lines 77-82 Link Here
77
				initializerFlowContext.parent,
77
				initializerFlowContext.parent,
78
				this,
78
				this,
79
				this.binding.thrownExceptions,
79
				this.binding.thrownExceptions,
80
				initializerFlowContext,
80
				this.scope,
81
				this.scope,
81
				FlowInfo.DEAD_END);
82
				FlowInfo.DEAD_END);
82
		initializerFlowContext.checkInitializerExceptions(
83
		initializerFlowContext.checkInitializerExceptions(
(-)compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java (-2 / +4 lines)
Lines 63-69 Link Here
63
				FieldBinding fieldBinding;
63
				FieldBinding fieldBinding;
64
				if ((fieldBinding = (FieldBinding) this.binding).isBlankFinal()
64
				if ((fieldBinding = (FieldBinding) this.binding).isBlankFinal()
65
						&& currentScope.needBlankFinalFieldInitializationCheck(fieldBinding)) {
65
						&& currentScope.needBlankFinalFieldInitializationCheck(fieldBinding)) {
66
					if (!flowInfo.isDefinitelyAssigned(fieldBinding)) {
66
					FlowInfo fieldInits = flowContext.getInitsForFinalBlankInitializationCheck(fieldBinding.declaringClass.original(), flowInfo);
67
					if (!fieldInits.isDefinitelyAssigned(fieldBinding)) {
67
						currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this);
68
						currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this);
68
					}
69
					}
69
				}
70
				}
Lines 149-155 Link Here
149
			// check if reading a final blank field
150
			// check if reading a final blank field
150
			FieldBinding fieldBinding = (FieldBinding) this.binding;
151
			FieldBinding fieldBinding = (FieldBinding) this.binding;
151
			if (fieldBinding.isBlankFinal() && currentScope.needBlankFinalFieldInitializationCheck(fieldBinding)) {
152
			if (fieldBinding.isBlankFinal() && currentScope.needBlankFinalFieldInitializationCheck(fieldBinding)) {
152
				if (!flowInfo.isDefinitelyAssigned(fieldBinding)) {
153
				FlowInfo fieldInits = flowContext.getInitsForFinalBlankInitializationCheck(fieldBinding.declaringClass.original(), flowInfo);
154
				if (!fieldInits.isDefinitelyAssigned(fieldBinding)) {
153
					currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this);
155
					currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this);
154
				}
156
				}
155
			}
157
			}
(-)compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java (-5 / +7 lines)
Lines 56-70 Link Here
56
56
57
}
57
}
58
58
59
public FlowInfo analyseAssignment(BlockScope currentScope, 	FlowContext flowContext, 	FlowInfo flowInfo, Assignment assignment, boolean isCompound) {
59
public FlowInfo analyseAssignment(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, Assignment assignment, boolean isCompound) {
60
	// compound assignment extra work
60
	// compound assignment extra work
61
	if (isCompound) { // check the variable part is initialized if blank final
61
	if (isCompound) { // check the variable part is initialized if blank final
62
		if (this.binding.isBlankFinal()
62
		if (this.binding.isBlankFinal()
63
			&& this.receiver.isThis()
63
			&& this.receiver.isThis()
64
			&& currentScope.needBlankFinalFieldInitializationCheck(this.binding)
64
			&& currentScope.needBlankFinalFieldInitializationCheck(this.binding)) {
65
			&& (!flowInfo.isDefinitelyAssigned(this.binding))) {
65
			FlowInfo fieldInits = flowContext.getInitsForFinalBlankInitializationCheck(this.binding.declaringClass.original(), flowInfo);
66
			currentScope.problemReporter().uninitializedBlankFinalField(this.binding, this);
66
			if (!fieldInits.isDefinitelyAssigned(this.binding)) {
67
			// we could improve error msg here telling "cannot use compound assignment on final blank field"
67
				currentScope.problemReporter().uninitializedBlankFinalField(this.binding, this);
68
				// we could improve error msg here telling "cannot use compound assignment on final blank field"
69
			}
68
		}
70
		}
69
		manageSyntheticAccessIfNecessary(currentScope, flowInfo, true /*read-access*/);
71
		manageSyntheticAccessIfNecessary(currentScope, flowInfo, true /*read-access*/);
70
	}
72
	}
(-)compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java (+1 lines)
Lines 68-73 Link Here
68
					initializationContext,
68
					initializationContext,
69
					this,
69
					this,
70
					this.binding.thrownExceptions,
70
					this.binding.thrownExceptions,
71
					null,
71
					this.scope,
72
					this.scope,
72
					FlowInfo.DEAD_END);
73
					FlowInfo.DEAD_END);
73
74
(-)compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java (-10 / +13 lines)
Lines 75-84 Link Here
75
			if (lastFieldBinding.isBlankFinal()
75
			if (lastFieldBinding.isBlankFinal()
76
				    && this.otherBindings != null // the last field binding is only assigned
76
				    && this.otherBindings != null // the last field binding is only assigned
77
	 				&& currentScope.needBlankFinalFieldInitializationCheck(lastFieldBinding)) {
77
	 				&& currentScope.needBlankFinalFieldInitializationCheck(lastFieldBinding)) {
78
				if (!flowInfo.isDefinitelyAssigned(lastFieldBinding)) {
78
				FlowInfo fieldInits = flowContext.getInitsForFinalBlankInitializationCheck(lastFieldBinding.declaringClass.original(), flowInfo);
79
					currentScope.problemReporter().uninitializedBlankFinalField(
79
				if (!fieldInits.isDefinitelyAssigned(lastFieldBinding)) {
80
						lastFieldBinding,
80
					currentScope.problemReporter().uninitializedBlankFinalField(lastFieldBinding, this);
81
						this);
82
				}
81
				}
83
			}
82
			}
84
			break;
83
			break;
Lines 116-124 Link Here
116
	if (isCompound) {
115
	if (isCompound) {
117
		if (otherBindingsCount == 0
116
		if (otherBindingsCount == 0
118
				&& lastFieldBinding.isBlankFinal()
117
				&& lastFieldBinding.isBlankFinal()
119
				&& currentScope.needBlankFinalFieldInitializationCheck(lastFieldBinding)
118
				&& currentScope.needBlankFinalFieldInitializationCheck(lastFieldBinding)) {
120
				&& (!flowInfo.isDefinitelyAssigned(lastFieldBinding))) {
119
			FlowInfo fieldInits = flowContext.getInitsForFinalBlankInitializationCheck(lastFieldBinding.declaringClass, flowInfo);
121
			currentScope.problemReporter().uninitializedBlankFinalField(lastFieldBinding, this);
120
			if (!fieldInits.isDefinitelyAssigned(lastFieldBinding)) {
121
				currentScope.problemReporter().uninitializedBlankFinalField(lastFieldBinding, this);
122
			}
122
		}
123
		}
123
		manageSyntheticAccessIfNecessary(currentScope, lastFieldBinding, otherBindingsCount, flowInfo);
124
		manageSyntheticAccessIfNecessary(currentScope, lastFieldBinding, otherBindingsCount, flowInfo);
124
	}
125
	}
Lines 176-184 Link Here
176
				FieldBinding fieldBinding = (FieldBinding) this.binding;
177
				FieldBinding fieldBinding = (FieldBinding) this.binding;
177
				// check if reading a final blank field
178
				// check if reading a final blank field
178
				if (fieldBinding.isBlankFinal()
179
				if (fieldBinding.isBlankFinal()
179
						&& currentScope.needBlankFinalFieldInitializationCheck(fieldBinding)
180
						&& currentScope.needBlankFinalFieldInitializationCheck(fieldBinding)) {
180
						&& !flowInfo.isDefinitelyAssigned(fieldBinding)) {
181
					FlowInfo fieldInits = flowContext.getInitsForFinalBlankInitializationCheck(fieldBinding.declaringClass.original(), flowInfo);
181
					currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this);
182
					if (!fieldInits.isDefinitelyAssigned(fieldBinding)) {
183
						currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this);
184
					}
182
				}
185
				}
183
			}
186
			}
184
			break;
187
			break;
(-)buildnotes_jdt-core.html (-1 / +3 lines)
Lines 49-55 Link Here
49
<h2>What's new in this drop</h2>
49
<h2>What's new in this drop</h2>
50
50
51
<h3>Problem Reports Fixed</h3>
51
<h3>Problem Reports Fixed</h3>
52
<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=262408">262408</a>
52
<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=257716">257716</a>
53
[compiler] Erroneous blank field field may not have been initialized
54
<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=262408">262408</a>
53
remove deprecated NamingConventions.VK_CONSTANT_FIELD
55
remove deprecated NamingConventions.VK_CONSTANT_FIELD
54
<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=262717">262717</a>
56
<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=262717">262717</a>
55
Wrong line numbers in classfile
57
Wrong line numbers in classfile
(-)eval/org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java (-1 / +2 lines)
Lines 59-65 Link Here
59
			FieldBinding fieldBinding;
59
			FieldBinding fieldBinding;
60
			if ((fieldBinding = (FieldBinding) this.binding).isBlankFinal()
60
			if ((fieldBinding = (FieldBinding) this.binding).isBlankFinal()
61
					&& currentScope.needBlankFinalFieldInitializationCheck(fieldBinding)) {
61
					&& currentScope.needBlankFinalFieldInitializationCheck(fieldBinding)) {
62
				if (!flowInfo.isDefinitelyAssigned(fieldBinding)) {
62
				FlowInfo fieldInits = flowContext.getInitsForFinalBlankInitializationCheck(fieldBinding.declaringClass.original(), flowInfo);
63
				if (!fieldInits.isDefinitelyAssigned(fieldBinding)) {
63
					currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this);
64
					currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this);
64
				}
65
				}
65
			}
66
			}
(-)compiler/org/eclipse/jdt/internal/compiler/flow/ExceptionHandlingFlowContext.java (-1 / +4 lines)
Lines 41-47 Link Here
41
	boolean isMethodContext;
41
	boolean isMethodContext;
42
42
43
	public UnconditionalFlowInfo initsOnReturn;
43
	public UnconditionalFlowInfo initsOnReturn;
44
44
	public FlowContext initializationParent; // special parent relationship only for initialization purpose
45
	
45
	// for dealing with anonymous constructor thrown exceptions
46
	// for dealing with anonymous constructor thrown exceptions
46
	public ArrayList extendedExceptions;
47
	public ArrayList extendedExceptions;
47
48
Lines 49-54 Link Here
49
		FlowContext parent,
50
		FlowContext parent,
50
		ASTNode associatedNode,
51
		ASTNode associatedNode,
51
		ReferenceBinding[] handledExceptions,
52
		ReferenceBinding[] handledExceptions,
53
		FlowContext initializationParent,
52
		BlockScope scope,
54
		BlockScope scope,
53
		UnconditionalFlowInfo flowInfo) {
55
		UnconditionalFlowInfo flowInfo) {
54
56
Lines 79-84 Link Here
79
		System.arraycopy(this.isReached, 0, this.isNeeded, 0, cacheSize);
81
		System.arraycopy(this.isReached, 0, this.isNeeded, 0, cacheSize);
80
	}
82
	}
81
	this.initsOnReturn = FlowInfo.DEAD_END;
83
	this.initsOnReturn = FlowInfo.DEAD_END;
84
	this.	initializationParent = initializationParent;
82
}
85
}
83
86
84
public void complainIfUnusedExceptionHandlers(AbstractMethodDeclaration method) {
87
public void complainIfUnusedExceptionHandlers(AbstractMethodDeclaration method) {
(-)compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java (-19 / +42 lines)
Lines 18-23 Link Here
18
import org.eclipse.jdt.internal.compiler.ast.Reference;
18
import org.eclipse.jdt.internal.compiler.ast.Reference;
19
import org.eclipse.jdt.internal.compiler.ast.SubRoutineStatement;
19
import org.eclipse.jdt.internal.compiler.ast.SubRoutineStatement;
20
import org.eclipse.jdt.internal.compiler.ast.TryStatement;
20
import org.eclipse.jdt.internal.compiler.ast.TryStatement;
21
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
21
import org.eclipse.jdt.internal.compiler.codegen.BranchLabel;
22
import org.eclipse.jdt.internal.compiler.codegen.BranchLabel;
22
import org.eclipse.jdt.internal.compiler.lookup.Binding;
23
import org.eclipse.jdt.internal.compiler.lookup.Binding;
23
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
24
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
Lines 44-49 Link Here
44
45
45
boolean deferNullDiagnostic, preemptNullDiagnostic;
46
boolean deferNullDiagnostic, preemptNullDiagnostic;
46
47
48
public static final int
49
  CAN_ONLY_NULL_NON_NULL = 0x0000,
50
  	// check against null and non null, with definite values -- comparisons
51
  CAN_ONLY_NULL = 0x0001,
52
  	// check against null, with definite values -- comparisons
53
  CAN_ONLY_NON_NULL = 0x0002,
54
	// check against non null, with definite values -- comparisons
55
  MAY_NULL = 0x0003,
56
	// check against null, with potential values -- NPE guard
57
  CHECK_MASK = 0x00FF,
58
  IN_COMPARISON_NULL = 0x0100,
59
  IN_COMPARISON_NON_NULL = 0x0200,
60
    // check happened in a comparison
61
  IN_ASSIGNMENT = 0x0300,
62
    // check happened in an assignment
63
  IN_INSTANCEOF = 0x0400,
64
    // check happened in an instanceof expression
65
  CONTEXT_MASK = ~CHECK_MASK;
66
47
public FlowContext(FlowContext parent, ASTNode associatedNode) {
67
public FlowContext(FlowContext parent, ASTNode associatedNode) {
48
	this.parent = parent;
68
	this.parent = parent;
49
	this.associatedNode = associatedNode;
69
	this.associatedNode = associatedNode;
Lines 287-292 Link Here
287
	return null;
307
	return null;
288
}
308
}
289
309
310
public FlowInfo getInitsForFinalBlankInitializationCheck(TypeBinding declaringType, FlowInfo flowInfo) {
311
	FlowContext current = this;
312
	FlowInfo inits = flowInfo;
313
	do {
314
		if (current instanceof InitializationFlowContext) {
315
			InitializationFlowContext initializationContext = (InitializationFlowContext) current;
316
			if (((TypeDeclaration)initializationContext.associatedNode).binding == declaringType) {
317
				return inits;
318
			}
319
			inits = initializationContext.initsBeforeContext;
320
			current = initializationContext.initializationParent;
321
		} else if (current instanceof ExceptionHandlingFlowContext) {
322
			ExceptionHandlingFlowContext exceptionContext = (ExceptionHandlingFlowContext) current;
323
			current = exceptionContext.initializationParent == null ? exceptionContext.parent : exceptionContext.initializationParent;
324
		} else {
325
			current = current.parent;
326
		}
327
	} while (current != null);
328
	// not found
329
	return null;
330
}
331
290
/*
332
/*
291
 * lookup through break labels
333
 * lookup through break labels
292
 */
334
 */
Lines 468-492 Link Here
468
	}
510
	}
469
}
511
}
470
512
471
public static final int
472
  CAN_ONLY_NULL_NON_NULL = 0x0000,
473
  	// check against null and non null, with definite values -- comparisons
474
  CAN_ONLY_NULL = 0x0001,
475
  	// check against null, with definite values -- comparisons
476
  CAN_ONLY_NON_NULL = 0x0002,
477
	// check against non null, with definite values -- comparisons
478
  MAY_NULL = 0x0003,
479
	// check against null, with potential values -- NPE guard
480
  CHECK_MASK = 0x00FF,
481
  IN_COMPARISON_NULL = 0x0100,
482
  IN_COMPARISON_NON_NULL = 0x0200,
483
    // check happened in a comparison
484
  IN_ASSIGNMENT = 0x0300,
485
    // check happened in an assignment
486
  IN_INSTANCEOF = 0x0400,
487
    // check happened in an instanceof expression
488
  CONTEXT_MASK = ~CHECK_MASK;
489
490
/**
513
/**
491
 * Record a null reference for use by deferred checks. Only looping or
514
 * Record a null reference for use by deferred checks. Only looping or
492
 * finally contexts really record that information. The context may
515
 * finally contexts really record that information. The context may
(-)compiler/org/eclipse/jdt/internal/compiler/flow/InitializationFlowContext.java (-6 / +5 lines)
Lines 21-42 Link Here
21
 *	try statements, exception handlers, etc...
21
 *	try statements, exception handlers, etc...
22
 */
22
 */
23
public class InitializationFlowContext extends ExceptionHandlingFlowContext {
23
public class InitializationFlowContext extends ExceptionHandlingFlowContext {
24
25
	public int exceptionCount;
24
	public int exceptionCount;
26
	public TypeBinding[] thrownExceptions = new TypeBinding[5];
25
	public TypeBinding[] thrownExceptions = new TypeBinding[5];
27
	public ASTNode[] exceptionThrowers = new ASTNode[5];
26
	public ASTNode[] exceptionThrowers = new ASTNode[5];
28
	public FlowInfo[] exceptionThrowerFlowInfos = new FlowInfo[5];
27
	public FlowInfo[] exceptionThrowerFlowInfos = new FlowInfo[5];
29
28
	public FlowInfo	initsBeforeContext;
30
	public InitializationFlowContext(
29
	
31
		FlowContext parent,
30
	public InitializationFlowContext(FlowContext parent, ASTNode associatedNode, FlowInfo initsBeforeContext, FlowContext initializationParent, BlockScope scope) {
32
		ASTNode associatedNode,
33
		BlockScope scope) {
34
		super(
31
		super(
35
			parent,
32
			parent,
36
			associatedNode,
33
			associatedNode,
37
			Binding.NO_EXCEPTIONS, // no exception allowed by default
34
			Binding.NO_EXCEPTIONS, // no exception allowed by default
35
			initializationParent,
38
			scope,
36
			scope,
39
			FlowInfo.DEAD_END);
37
			FlowInfo.DEAD_END);
38
		this.initsBeforeContext = initsBeforeContext;
40
	}
39
	}
41
40
42
	public void checkInitializerExceptions(
41
	public void checkInitializerExceptions(

Return to bug 257716