|
Lines 100-117
Link Here
|
| 100 |
for (int i = 0; i < this.nullCount; i++) { |
100 |
for (int i = 0; i < this.nullCount; i++) { |
| 101 |
Expression expression = this.nullReferences[i]; |
101 |
Expression expression = this.nullReferences[i]; |
| 102 |
// final local variable |
102 |
// final local variable |
| 103 |
VariableBinding local = this.nullVariables[i]; |
103 |
VariableBinding var = this.nullVariables[i]; |
| 104 |
switch (this.nullCheckTypes[i]) { |
104 |
switch (this.nullCheckTypes[i]) { |
| 105 |
case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL: |
105 |
case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL: |
| 106 |
case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL: |
106 |
case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL: |
| 107 |
if (flowInfo.isDefinitelyNonNull(local)) { |
107 |
if (flowInfo.isDefinitelyNonNull(var)) { |
| 108 |
if (this.nullCheckTypes[i] == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) { |
108 |
if (this.nullCheckTypes[i] == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) { |
| 109 |
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { |
109 |
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { |
| 110 |
scope.problemReporter().variableRedundantCheckOnNonNull(local, expression); |
110 |
scope.problemReporter().variableRedundantCheckOnNonNull(var, expression); |
| 111 |
} |
111 |
} |
| 112 |
} else { |
112 |
} else { |
| 113 |
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { |
113 |
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { |
| 114 |
scope.problemReporter().variableNonNullComparedToNull(local, expression); |
114 |
scope.problemReporter().variableNonNullComparedToNull(var, expression); |
| 115 |
} |
115 |
} |
| 116 |
} |
116 |
} |
| 117 |
continue; |
117 |
continue; |
|
Lines 121-166
Link Here
|
| 121 |
case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL: |
121 |
case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL: |
| 122 |
case CAN_ONLY_NULL | IN_ASSIGNMENT: |
122 |
case CAN_ONLY_NULL | IN_ASSIGNMENT: |
| 123 |
case CAN_ONLY_NULL | IN_INSTANCEOF: |
123 |
case CAN_ONLY_NULL | IN_INSTANCEOF: |
| 124 |
if (flowInfo.isDefinitelyNull(local)) { |
124 |
if (flowInfo.isDefinitelyNull(var)) { |
| 125 |
switch(this.nullCheckTypes[i] & CONTEXT_MASK) { |
125 |
switch(this.nullCheckTypes[i] & CONTEXT_MASK) { |
| 126 |
case FlowContext.IN_COMPARISON_NULL: |
126 |
case FlowContext.IN_COMPARISON_NULL: |
| 127 |
if (((this.nullCheckTypes[i] & CHECK_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning |
127 |
if (((this.nullCheckTypes[i] & CHECK_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning |
| 128 |
scope.problemReporter().variableNullReference(local, expression); |
128 |
scope.problemReporter().variableNullReference(var, expression); |
| 129 |
continue; |
129 |
continue; |
| 130 |
} |
130 |
} |
| 131 |
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { |
131 |
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { |
| 132 |
scope.problemReporter().variableRedundantCheckOnNull(local, expression); |
132 |
scope.problemReporter().variableRedundantCheckOnNull(var, expression); |
| 133 |
} |
133 |
} |
| 134 |
continue; |
134 |
continue; |
| 135 |
case FlowContext.IN_COMPARISON_NON_NULL: |
135 |
case FlowContext.IN_COMPARISON_NON_NULL: |
| 136 |
if (((this.nullCheckTypes[i] & CHECK_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning |
136 |
if (((this.nullCheckTypes[i] & CHECK_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning |
| 137 |
scope.problemReporter().variableNullReference(local, expression); |
137 |
scope.problemReporter().variableNullReference(var, expression); |
| 138 |
continue; |
138 |
continue; |
| 139 |
} |
139 |
} |
| 140 |
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { |
140 |
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { |
| 141 |
scope.problemReporter().variableNullComparedToNonNull(local, expression); |
141 |
scope.problemReporter().variableNullComparedToNonNull(var, expression); |
| 142 |
} |
142 |
} |
| 143 |
continue; |
143 |
continue; |
| 144 |
case FlowContext.IN_ASSIGNMENT: |
144 |
case FlowContext.IN_ASSIGNMENT: |
| 145 |
scope.problemReporter().variableRedundantNullAssignment(local, expression); |
145 |
scope.problemReporter().variableRedundantNullAssignment(var, expression); |
| 146 |
continue; |
146 |
continue; |
| 147 |
case FlowContext.IN_INSTANCEOF: |
147 |
case FlowContext.IN_INSTANCEOF: |
| 148 |
scope.problemReporter().variableNullInstanceof(local, expression); |
148 |
scope.problemReporter().variableNullInstanceof(var, expression); |
| 149 |
continue; |
149 |
continue; |
| 150 |
} |
150 |
} |
| 151 |
} else if (flowInfo.isPotentiallyNull(local)) { |
151 |
} else if (flowInfo.isPotentiallyNull(var)) { |
| 152 |
switch(this.nullCheckTypes[i] & CONTEXT_MASK) { |
152 |
switch(this.nullCheckTypes[i] & CONTEXT_MASK) { |
| 153 |
case FlowContext.IN_COMPARISON_NULL: |
153 |
case FlowContext.IN_COMPARISON_NULL: |
| 154 |
this.nullReferences[i] = null; |
154 |
this.nullReferences[i] = null; |
| 155 |
if (((this.nullCheckTypes[i] & CHECK_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning |
155 |
if (((this.nullCheckTypes[i] & CHECK_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning |
| 156 |
scope.problemReporter().variablePotentialNullReference(local, expression); |
156 |
scope.problemReporter().variablePotentialNullReference(var, expression); |
| 157 |
continue; |
157 |
continue; |
| 158 |
} |
158 |
} |
| 159 |
break; |
159 |
break; |
| 160 |
case FlowContext.IN_COMPARISON_NON_NULL: |
160 |
case FlowContext.IN_COMPARISON_NON_NULL: |
| 161 |
this.nullReferences[i] = null; |
161 |
this.nullReferences[i] = null; |
| 162 |
if (((this.nullCheckTypes[i] & CHECK_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning |
162 |
if (((this.nullCheckTypes[i] & CHECK_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning |
| 163 |
scope.problemReporter().variablePotentialNullReference(local, expression); |
163 |
scope.problemReporter().variablePotentialNullReference(var, expression); |
| 164 |
continue; |
164 |
continue; |
| 165 |
} |
165 |
} |
| 166 |
break; |
166 |
break; |
|
Lines 168-183
Link Here
|
| 168 |
} |
168 |
} |
| 169 |
break; |
169 |
break; |
| 170 |
case MAY_NULL: |
170 |
case MAY_NULL: |
| 171 |
if (flowInfo.isDefinitelyNull(local)) { |
171 |
if (flowInfo.isDefinitelyNull(var)) { |
| 172 |
scope.problemReporter().variableNullReference(local, expression); |
172 |
scope.problemReporter().variableNullReference(var, expression); |
| 173 |
continue; |
173 |
continue; |
| 174 |
} |
174 |
} |
| 175 |
if (flowInfo.isPotentiallyNull(local)) { |
175 |
if (flowInfo.isPotentiallyNull(var)) { |
| 176 |
scope.problemReporter().variablePotentialNullReference(local, expression); |
176 |
scope.problemReporter().variablePotentialNullReference(var, expression); |
| 177 |
} |
177 |
} |
| 178 |
break; |
178 |
break; |
| 179 |
case ASSIGN_TO_NONNULL: |
179 |
case ASSIGN_TO_NONNULL: |
| 180 |
int nullStatus = flowInfo.nullStatus(local); |
180 |
int nullStatus = flowInfo.nullStatus(var); |
| 181 |
if (nullStatus != FlowInfo.NON_NULL) { |
181 |
if (nullStatus != FlowInfo.NON_NULL) { |
| 182 |
char[][] annotationName = scope.environment().getNonNullAnnotationName(); |
182 |
char[][] annotationName = scope.environment().getNonNullAnnotationName(); |
| 183 |
scope.problemReporter().nullityMismatch(expression, this.expectedTypes[i], nullStatus, annotationName); |
183 |
scope.problemReporter().nullityMismatch(expression, this.expectedTypes[i], nullStatus, annotationName); |
|
Lines 228-236
Link Here
|
| 228 |
return true; |
228 |
return true; |
| 229 |
} |
229 |
} |
| 230 |
|
230 |
|
| 231 |
public void recordUsingNullReference(Scope scope, VariableBinding local, |
231 |
public void recordUsingNullReference(Scope scope, VariableBinding var, |
| 232 |
Expression reference, int checkType, FlowInfo flowInfo) { |
232 |
Expression reference, int checkType, FlowInfo flowInfo) { |
| 233 |
if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0 && !flowInfo.isDefinitelyUnknown(local)) { |
233 |
if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0 && !flowInfo.isDefinitelyUnknown(var)) { |
| 234 |
if ((this.tagBits & FlowContext.DEFER_NULL_DIAGNOSTIC) != 0) { // within an enclosing loop, be conservative |
234 |
if ((this.tagBits & FlowContext.DEFER_NULL_DIAGNOSTIC) != 0) { // within an enclosing loop, be conservative |
| 235 |
switch (checkType) { |
235 |
switch (checkType) { |
| 236 |
case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL: |
236 |
case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL: |
|
Lines 239-306
Link Here
|
| 239 |
case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL: |
239 |
case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL: |
| 240 |
case CAN_ONLY_NULL | IN_ASSIGNMENT: |
240 |
case CAN_ONLY_NULL | IN_ASSIGNMENT: |
| 241 |
case CAN_ONLY_NULL | IN_INSTANCEOF: |
241 |
case CAN_ONLY_NULL | IN_INSTANCEOF: |
| 242 |
if (flowInfo.cannotBeNull(local)) { |
242 |
if (flowInfo.cannotBeNull(var)) { |
| 243 |
if (checkType == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) { |
243 |
if (checkType == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) { |
| 244 |
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { |
244 |
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { |
| 245 |
scope.problemReporter().variableRedundantCheckOnNonNull(local, reference); |
245 |
scope.problemReporter().variableRedundantCheckOnNonNull(var, reference); |
| 246 |
} |
246 |
} |
| 247 |
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) { |
247 |
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(var)) { |
| 248 |
flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS); |
248 |
flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS); |
| 249 |
} |
249 |
} |
| 250 |
} else if (checkType == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL)) { |
250 |
} else if (checkType == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL)) { |
| 251 |
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { |
251 |
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { |
| 252 |
scope.problemReporter().variableNonNullComparedToNull(local, reference); |
252 |
scope.problemReporter().variableNonNullComparedToNull(var, reference); |
| 253 |
} |
253 |
} |
| 254 |
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) { |
254 |
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(var)) { |
| 255 |
flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS); |
255 |
flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS); |
| 256 |
} |
256 |
} |
| 257 |
} |
257 |
} |
| 258 |
return; |
258 |
return; |
| 259 |
} |
259 |
} |
| 260 |
if (flowInfo.canOnlyBeNull(local)) { |
260 |
if (flowInfo.canOnlyBeNull(var)) { |
| 261 |
switch(checkType & CONTEXT_MASK) { |
261 |
switch(checkType & CONTEXT_MASK) { |
| 262 |
case FlowContext.IN_COMPARISON_NULL: |
262 |
case FlowContext.IN_COMPARISON_NULL: |
| 263 |
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning |
263 |
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning |
| 264 |
scope.problemReporter().variableNullReference(local, reference); |
264 |
scope.problemReporter().variableNullReference(var, reference); |
| 265 |
return; |
265 |
return; |
| 266 |
} |
266 |
} |
| 267 |
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { |
267 |
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { |
| 268 |
scope.problemReporter().variableRedundantCheckOnNull(local, reference); |
268 |
scope.problemReporter().variableRedundantCheckOnNull(var, reference); |
| 269 |
} |
269 |
} |
| 270 |
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) { |
270 |
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(var)) { |
| 271 |
flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS); |
271 |
flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS); |
| 272 |
} |
272 |
} |
| 273 |
return; |
273 |
return; |
| 274 |
case FlowContext.IN_COMPARISON_NON_NULL: |
274 |
case FlowContext.IN_COMPARISON_NON_NULL: |
| 275 |
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning |
275 |
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning |
| 276 |
scope.problemReporter().variableNullReference(local, reference); |
276 |
scope.problemReporter().variableNullReference(var, reference); |
| 277 |
return; |
277 |
return; |
| 278 |
} |
278 |
} |
| 279 |
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { |
279 |
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { |
| 280 |
scope.problemReporter().variableNullComparedToNonNull(local, reference); |
280 |
scope.problemReporter().variableNullComparedToNonNull(var, reference); |
| 281 |
} |
281 |
} |
| 282 |
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) { |
282 |
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(var)) { |
| 283 |
flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS); |
283 |
flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS); |
| 284 |
} |
284 |
} |
| 285 |
return; |
285 |
return; |
| 286 |
case FlowContext.IN_ASSIGNMENT: |
286 |
case FlowContext.IN_ASSIGNMENT: |
| 287 |
scope.problemReporter().variableRedundantNullAssignment(local, reference); |
287 |
scope.problemReporter().variableRedundantNullAssignment(var, reference); |
| 288 |
return; |
288 |
return; |
| 289 |
case FlowContext.IN_INSTANCEOF: |
289 |
case FlowContext.IN_INSTANCEOF: |
| 290 |
scope.problemReporter().variableNullInstanceof(local, reference); |
290 |
scope.problemReporter().variableNullInstanceof(var, reference); |
| 291 |
return; |
291 |
return; |
| 292 |
} |
292 |
} |
| 293 |
} else if (flowInfo.isPotentiallyNull(local)) { |
293 |
} else if (flowInfo.isPotentiallyNull(var)) { |
| 294 |
switch(checkType & CONTEXT_MASK) { |
294 |
switch(checkType & CONTEXT_MASK) { |
| 295 |
case FlowContext.IN_COMPARISON_NULL: |
295 |
case FlowContext.IN_COMPARISON_NULL: |
| 296 |
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning |
296 |
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning |
| 297 |
scope.problemReporter().variablePotentialNullReference(local, reference); |
297 |
scope.problemReporter().variablePotentialNullReference(var, reference); |
| 298 |
return; |
298 |
return; |
| 299 |
} |
299 |
} |
| 300 |
break; |
300 |
break; |
| 301 |
case FlowContext.IN_COMPARISON_NON_NULL: |
301 |
case FlowContext.IN_COMPARISON_NON_NULL: |
| 302 |
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning |
302 |
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning |
| 303 |
scope.problemReporter().variablePotentialNullReference(local, reference); |
303 |
scope.problemReporter().variablePotentialNullReference(var, reference); |
| 304 |
return; |
304 |
return; |
| 305 |
} |
305 |
} |
| 306 |
break; |
306 |
break; |
|
Lines 308-318
Link Here
|
| 308 |
} |
308 |
} |
| 309 |
break; |
309 |
break; |
| 310 |
case MAY_NULL : |
310 |
case MAY_NULL : |
| 311 |
if (flowInfo.cannotBeNull(local)) { |
311 |
if (flowInfo.cannotBeNull(var)) { |
| 312 |
return; |
312 |
return; |
| 313 |
} |
313 |
} |
| 314 |
if (flowInfo.canOnlyBeNull(local)) { |
314 |
if (flowInfo.canOnlyBeNull(var)) { |
| 315 |
scope.problemReporter().variableNullReference(local, reference); |
315 |
scope.problemReporter().variableNullReference(var, reference); |
| 316 |
return; |
316 |
return; |
| 317 |
} |
317 |
} |
| 318 |
break; |
318 |
break; |
|
Lines 324-342
Link Here
|
| 324 |
switch (checkType) { |
324 |
switch (checkType) { |
| 325 |
case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL: |
325 |
case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL: |
| 326 |
case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL: |
326 |
case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL: |
| 327 |
if (flowInfo.isDefinitelyNonNull(local)) { |
327 |
if (flowInfo.isDefinitelyNonNull(var)) { |
| 328 |
if (checkType == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) { |
328 |
if (checkType == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) { |
| 329 |
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { |
329 |
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { |
| 330 |
scope.problemReporter().variableRedundantCheckOnNonNull(local, reference); |
330 |
scope.problemReporter().variableRedundantCheckOnNonNull(var, reference); |
| 331 |
} |
331 |
} |
| 332 |
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) { |
332 |
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(var)) { |
| 333 |
flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS); |
333 |
flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS); |
| 334 |
} |
334 |
} |
| 335 |
} else { |
335 |
} else { |
| 336 |
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { |
336 |
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { |
| 337 |
scope.problemReporter().variableNonNullComparedToNull(local, reference); |
337 |
scope.problemReporter().variableNonNullComparedToNull(var, reference); |
| 338 |
} |
338 |
} |
| 339 |
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) { |
339 |
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(var)) { |
| 340 |
flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS); |
340 |
flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS); |
| 341 |
} |
341 |
} |
| 342 |
} |
342 |
} |
|
Lines 347-396
Link Here
|
| 347 |
case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL: |
347 |
case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL: |
| 348 |
case CAN_ONLY_NULL | IN_ASSIGNMENT: |
348 |
case CAN_ONLY_NULL | IN_ASSIGNMENT: |
| 349 |
case CAN_ONLY_NULL | IN_INSTANCEOF: |
349 |
case CAN_ONLY_NULL | IN_INSTANCEOF: |
| 350 |
if (flowInfo.isDefinitelyNull(local)) { |
350 |
if (flowInfo.isDefinitelyNull(var)) { |
| 351 |
switch(checkType & CONTEXT_MASK) { |
351 |
switch(checkType & CONTEXT_MASK) { |
| 352 |
case FlowContext.IN_COMPARISON_NULL: |
352 |
case FlowContext.IN_COMPARISON_NULL: |
| 353 |
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning |
353 |
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning |
| 354 |
scope.problemReporter().variableNullReference(local, reference); |
354 |
scope.problemReporter().variableNullReference(var, reference); |
| 355 |
return; |
355 |
return; |
| 356 |
} |
356 |
} |
| 357 |
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { |
357 |
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { |
| 358 |
scope.problemReporter().variableRedundantCheckOnNull(local, reference); |
358 |
scope.problemReporter().variableRedundantCheckOnNull(var, reference); |
| 359 |
} |
359 |
} |
| 360 |
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) { |
360 |
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(var)) { |
| 361 |
flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS); |
361 |
flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS); |
| 362 |
} |
362 |
} |
| 363 |
return; |
363 |
return; |
| 364 |
case FlowContext.IN_COMPARISON_NON_NULL: |
364 |
case FlowContext.IN_COMPARISON_NON_NULL: |
| 365 |
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning |
365 |
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning |
| 366 |
scope.problemReporter().variableNullReference(local, reference); |
366 |
scope.problemReporter().variableNullReference(var, reference); |
| 367 |
return; |
367 |
return; |
| 368 |
} |
368 |
} |
| 369 |
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { |
369 |
if ((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) { |
| 370 |
scope.problemReporter().variableNullComparedToNonNull(local, reference); |
370 |
scope.problemReporter().variableNullComparedToNonNull(var, reference); |
| 371 |
} |
371 |
} |
| 372 |
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(local)) { |
372 |
if (!flowInfo.isMarkedAsNullOrNonNullInAssertExpression(var)) { |
| 373 |
flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS); |
373 |
flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS); |
| 374 |
} |
374 |
} |
| 375 |
return; |
375 |
return; |
| 376 |
case FlowContext.IN_ASSIGNMENT: |
376 |
case FlowContext.IN_ASSIGNMENT: |
| 377 |
scope.problemReporter().variableRedundantNullAssignment(local, reference); |
377 |
scope.problemReporter().variableRedundantNullAssignment(var, reference); |
| 378 |
return; |
378 |
return; |
| 379 |
case FlowContext.IN_INSTANCEOF: |
379 |
case FlowContext.IN_INSTANCEOF: |
| 380 |
scope.problemReporter().variableNullInstanceof(local, reference); |
380 |
scope.problemReporter().variableNullInstanceof(var, reference); |
| 381 |
return; |
381 |
return; |
| 382 |
} |
382 |
} |
| 383 |
} else if (flowInfo.isPotentiallyNull(local)) { |
383 |
} else if (flowInfo.isPotentiallyNull(var)) { |
| 384 |
switch(checkType & CONTEXT_MASK) { |
384 |
switch(checkType & CONTEXT_MASK) { |
| 385 |
case FlowContext.IN_COMPARISON_NULL: |
385 |
case FlowContext.IN_COMPARISON_NULL: |
| 386 |
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning |
386 |
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning |
| 387 |
scope.problemReporter().variablePotentialNullReference(local, reference); |
387 |
scope.problemReporter().variablePotentialNullReference(var, reference); |
| 388 |
return; |
388 |
return; |
| 389 |
} |
389 |
} |
| 390 |
break; |
390 |
break; |
| 391 |
case FlowContext.IN_COMPARISON_NON_NULL: |
391 |
case FlowContext.IN_COMPARISON_NON_NULL: |
| 392 |
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning |
392 |
if (((checkType & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning |
| 393 |
scope.problemReporter().variablePotentialNullReference(local, reference); |
393 |
scope.problemReporter().variablePotentialNullReference(var, reference); |
| 394 |
return; |
394 |
return; |
| 395 |
} |
395 |
} |
| 396 |
break; |
396 |
break; |
|
Lines 398-412
Link Here
|
| 398 |
} |
398 |
} |
| 399 |
break; |
399 |
break; |
| 400 |
case MAY_NULL : |
400 |
case MAY_NULL : |
| 401 |
if (flowInfo.isDefinitelyNull(local)) { |
401 |
if (flowInfo.isDefinitelyNull(var)) { |
| 402 |
scope.problemReporter().variableNullReference(local, reference); |
402 |
scope.problemReporter().variableNullReference(var, reference); |
| 403 |
return; |
403 |
return; |
| 404 |
} |
404 |
} |
| 405 |
if (flowInfo.isPotentiallyNull(local)) { |
405 |
if (flowInfo.isPotentiallyNull(var)) { |
| 406 |
scope.problemReporter().variablePotentialNullReference(local, reference); |
406 |
scope.problemReporter().variablePotentialNullReference(var, reference); |
| 407 |
return; |
407 |
return; |
| 408 |
} |
408 |
} |
| 409 |
if (flowInfo.isDefinitelyNonNull(local)) { |
409 |
if (flowInfo.isDefinitelyNonNull(var)) { |
| 410 |
return; // shortcut: cannot be null |
410 |
return; // shortcut: cannot be null |
| 411 |
} |
411 |
} |
| 412 |
break; |
412 |
break; |
|
Lines 419-425
Link Here
|
| 419 |
if(((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) || checkType == MAY_NULL |
419 |
if(((this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING) == 0) || checkType == MAY_NULL |
| 420 |
|| (checkType & CONTEXT_MASK) == FlowContext.IN_ASSIGNMENT |
420 |
|| (checkType & CONTEXT_MASK) == FlowContext.IN_ASSIGNMENT |
| 421 |
|| (checkType & CONTEXT_MASK) == FlowContext.IN_INSTANCEOF) { |
421 |
|| (checkType & CONTEXT_MASK) == FlowContext.IN_INSTANCEOF) { |
| 422 |
recordNullReference(local, reference, checkType); |
422 |
recordNullReference(var, reference, checkType); |
| 423 |
} |
423 |
} |
| 424 |
// prepare to re-check with try/catch flow info |
424 |
// prepare to re-check with try/catch flow info |
| 425 |
} |
425 |
} |
|
Lines 435-441
Link Here
|
| 435 |
} |
435 |
} |
| 436 |
} |
436 |
} |
| 437 |
|
437 |
|
| 438 |
protected void recordNullReference(VariableBinding local, |
438 |
protected void recordNullReference(VariableBinding var, |
| 439 |
Expression expression, int status) { |
439 |
Expression expression, int status) { |
| 440 |
if (this.nullCount == 0) { |
440 |
if (this.nullCount == 0) { |
| 441 |
this.nullVariables = new VariableBinding[5]; |
441 |
this.nullVariables = new VariableBinding[5]; |
|
Lines 454-460
Link Here
|
| 454 |
this.nullCheckTypes = new int[newLength], 0, |
454 |
this.nullCheckTypes = new int[newLength], 0, |
| 455 |
this.nullCount); |
455 |
this.nullCount); |
| 456 |
} |
456 |
} |
| 457 |
this.nullVariables[this.nullCount] = local; |
457 |
this.nullVariables[this.nullCount] = var; |
| 458 |
this.nullReferences[this.nullCount] = expression; |
458 |
this.nullReferences[this.nullCount] = expression; |
| 459 |
this.nullCheckTypes[this.nullCount++] = status; |
459 |
this.nullCheckTypes[this.nullCount++] = status; |
| 460 |
} |
460 |
} |