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

Collapse All | Expand All

(-)compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java (-21 / +41 lines)
Lines 352-363 Link Here
352
								ReferenceBinding interfaceType = (ReferenceBinding) expressionType;
352
								ReferenceBinding interfaceType = (ReferenceBinding) expressionType;
353
								match = interfaceType.findSuperTypeWithSameErasure(castType);
353
								match = interfaceType.findSuperTypeWithSameErasure(castType);
354
								if (match != null) {
354
								if (match != null) {
355
									return checkUnsafeCast(scope, castType, interfaceType, match, false);
355
									if (use15specifics) {
356
										return checkUnsafeCast(scope, castType, interfaceType, match, false);
357
									}
358
									return true;
356
								}
359
								}
357
								tagAsNeedCheckCast();
360
								tagAsNeedCheckCast();
358
								match = castType.findSuperTypeWithSameErasure(interfaceType);
361
								match = castType.findSuperTypeWithSameErasure(interfaceType);
359
								if (match != null) {
362
								if (match != null) {
360
									return checkUnsafeCast(scope, castType, interfaceType, match, true);
363
									if (use15specifics) {
364
										return checkUnsafeCast(scope, castType, interfaceType, match, true);
365
									}
366
									return true;
361
								}
367
								}
362
								if (use15specifics) {
368
								if (use15specifics) {
363
									checkUnsafeCast(scope, castType, expressionType, null /*no match*/, true);
369
									checkUnsafeCast(scope, castType, expressionType, null /*no match*/, true);
Lines 387-415 Link Here
387
									tagAsUnnecessaryCast(scope, castType);
393
									tagAsUnnecessaryCast(scope, castType);
388
									return true;
394
									return true;
389
								}
395
								}
390
								if (((ReferenceBinding) castType).isFinal()) {
396
								// can only be a downcast
391
									// no subclass for castType, thus compile-time check is valid
397
								tagAsNeedCheckCast();
392
									match = castType.findSuperTypeWithSameErasure(expressionType);
398
								match = castType.findSuperTypeWithSameErasure(expressionType);
393
									if (match == null) {
399
								if (match != null) {
394
										return false;
400
									if (use15specifics) {
401
										return checkUnsafeCast(scope, castType, expressionType, match, true);
395
									}
402
									}
403
									return true;
404
								}
405
								if (((ReferenceBinding) castType).isFinal()) {
406
									// no subclass for castType, thus compile-time check is invalid
407
									return false;
396
								}
408
								}
397
								if (use15specifics) {
409
								if (use15specifics) {
410
									checkUnsafeCast(scope, castType, expressionType, null /*no match*/, true);
398
									// ensure there is no collision between both interfaces: i.e. I1 extends List<String>, I2 extends List<Object>
411
									// ensure there is no collision between both interfaces: i.e. I1 extends List<String>, I2 extends List<Object>
399
									if (((ReferenceBinding)castType).hasIncompatibleSuperType((ReferenceBinding) expressionType)) {
412
									if (((ReferenceBinding)castType).hasIncompatibleSuperType((ReferenceBinding) expressionType)) {
400
										return false;
413
										return false;
401
									}
414
									}
402
								}
415
								}
416
								return true;
403
							}
417
							}
404
					}
418
					}
405
					tagAsNeedCheckCast();
406
					return true;
407
				} else {
419
				} else {
408
					switch (castType.kind()) {
420
					switch (castType.kind()) {
409
						case Binding.ARRAY_TYPE :
421
						case Binding.ARRAY_TYPE :
410
							// ( ARRAY ) CLASS
422
							// ( ARRAY ) CLASS
411
							if (expressionType.id == T_JavaLangObject) { // potential runtime error
423
							if (expressionType.id == T_JavaLangObject) { // potential runtime error
412
								checkUnsafeCast(scope, castType, expressionType, expressionType, true);
424
								if (use15specifics) checkUnsafeCast(scope, castType, expressionType, expressionType, true);
413
								tagAsNeedCheckCast();
425
								tagAsNeedCheckCast();
414
								return true;
426
								return true;
415
							}
427
							}
Lines 429-449 Link Here
429
								// ( INTERFACE ) CLASS
441
								// ( INTERFACE ) CLASS
430
								ReferenceBinding refExprType = (ReferenceBinding) expressionType;
442
								ReferenceBinding refExprType = (ReferenceBinding) expressionType;
431
								match = refExprType.findSuperTypeWithSameErasure(castType);
443
								match = refExprType.findSuperTypeWithSameErasure(castType);
432
								if (refExprType.isFinal()) {
444
								if (match != null) {
433
									// unless final a subclass may implement the interface ==> no check at compile time
445
									if (use15specifics) {
434
									if (match == null) {
435
										return false;
436
									}
437
									return checkUnsafeCast(scope, castType, expressionType, match, false);
438
								} else {
439
									if (match != null) {
440
										return checkUnsafeCast(scope, castType, expressionType, match, false);
446
										return checkUnsafeCast(scope, castType, expressionType, match, false);
441
									}
447
									}
448
									return true;
449
								}
450
								// unless final a subclass may implement the interface ==> no check at compile time
451
								if (refExprType.isFinal()) {
452
									return false;
442
								}
453
								}
443
								tagAsNeedCheckCast();
454
								tagAsNeedCheckCast();
444
								match = castType.findSuperTypeWithSameErasure(expressionType);
455
								match = castType.findSuperTypeWithSameErasure(expressionType);
445
								if (match != null) {
456
								if (match != null) {
446
									return checkUnsafeCast(scope, castType, expressionType, match, true);
457
									if (use15specifics) {
458
										return checkUnsafeCast(scope, castType, expressionType, match, true);
459
									}
460
									return true;
447
								}
461
								}
448
								if (use15specifics) {
462
								if (use15specifics) {
449
									checkUnsafeCast(scope, castType, expressionType, null /*no match*/, true);
463
									checkUnsafeCast(scope, castType, expressionType, null /*no match*/, true);
Lines 457-468 Link Here
457
								match = expressionType.findSuperTypeWithSameErasure(castType);
471
								match = expressionType.findSuperTypeWithSameErasure(castType);
458
								if (match != null) {
472
								if (match != null) {
459
									if (expression != null && castType.id == T_JavaLangString) this.constant = expression.constant; // (String) cst is still a constant
473
									if (expression != null && castType.id == T_JavaLangString) this.constant = expression.constant; // (String) cst is still a constant
460
									return checkUnsafeCast(scope, castType, expressionType, match, false);
474
									if (use15specifics) {
475
										return checkUnsafeCast(scope, castType, expressionType, match, false);
476
									} 
477
									return true;
461
								}
478
								}
462
								match = castType.findSuperTypeWithSameErasure(expressionType);
479
								match = castType.findSuperTypeWithSameErasure(expressionType);
463
								if (match != null) {
480
								if (match != null) {
464
									tagAsNeedCheckCast();
481
									tagAsNeedCheckCast();
465
									return checkUnsafeCast(scope, castType, expressionType, match, true);
482
									if (use15specifics) {
483
										return checkUnsafeCast(scope, castType, expressionType, match, true);
484
									}
485
									return true;
466
								}
486
								}
467
								return false;
487
								return false;
468
							}
488
							}
(-)compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java (-30 / +55 lines)
Lines 278-314 Link Here
278
			}
278
			}
279
			return true;
279
			return true;
280
		}
280
		}
281
		boolean isCastingToBoundParameterized;
281
		if (match != null && match.isProvablyDistinctFrom(isNarrowing ? expressionType : castType, 0)) {
282
		if (match != null && (
282
			return false; 
283
				(isCastingToBoundParameterized = castType.isBoundParameterizedType())
283
		}
284
				|| 	expressionType.isBoundParameterizedType())) {
284
		switch (castType.kind()) {
285
			
285
			case Binding.PARAMETERIZED_TYPE :
286
			if (match.isProvablyDistinctFrom(isNarrowing ? expressionType : castType, 0)) {
286
				if (castType.isBoundParameterizedType()) {
287
				return false; 
287
					if (match == null) { // unrelated types
288
			}
288
						this.bits |= UnsafeCast;
289
			if (isCastingToBoundParameterized 
289
						return true;
290
					&& (isNarrowing ? !expressionType.isEquivalentTo(match) : !match.isEquivalentTo(castType))) {
290
					}
291
				this.bits |= UnsafeCast;
291
					switch (match.kind()) {
292
				return true;
292
						case Binding.PARAMETERIZED_TYPE :
293
			} else if ((castType.tagBits & TagBits.HasDirectWildcard) == 0
293
							if (isNarrowing) {
294
					&& (!match.isParameterizedType() || expressionType.isRawType())) {
294
								// [JLS 5.5] T <: S
295
				this.bits |= UnsafeCast;
295
								if (expressionType.isRawType() || !expressionType.isEquivalentTo(match)) {
296
				return true;
296
									this.bits |= UnsafeCast;
297
			}
297
									return true;
298
		} else if (isNarrowing) {
298
								}
299
			TypeBinding leafType = castType.leafComponentType();
299
								// [JLS 5.5] S has no subtype X != T, such that |X| == |T|
300
			if (expressionType.id == T_JavaLangObject && castType.isArrayType() && leafType.isBoundParameterizedType()) {
300
								TypeBinding genericCastType = castType.erasure(); // jump to generic type
301
				this.bits |= UnsafeCast;
301
								TypeBinding genericMatch = genericCastType.findSuperTypeWithSameErasure(expressionType);
302
				return true;
302
								if (genericMatch == match) {
303
			}
303
									this.bits |= UnsafeCast;
304
			if (match == null && castType.isBoundParameterizedType()) { // cast between unrelated types
304
								}
305
				this.bits |= UnsafeCast;
305
								return true;
306
				return true;
306
							} else {
307
			}
307
								// [JLS 5.5] T >: S
308
			if (leafType.isTypeVariable()) {
308
								if (!match.isEquivalentTo(castType)) {
309
									this.bits |= UnsafeCast;
310
									return true;
311
								}
312
							}
313
							break;
314
						case Binding.RAW_TYPE :
315
							this.bits |= UnsafeCast; // upcast since castType is known to be bound paramType
316
							return true;
317
						default :
318
							if (isNarrowing){
319
								// match is not parameterized or raw, then any other subtype of match will erase  to |T|
320
								this.bits |= UnsafeCast;
321
								return true;
322
							}
323
							break;
324
					}
325
				}
326
				break;
327
			case Binding.ARRAY_TYPE :
328
				TypeBinding leafType = castType.leafComponentType();
329
				if (isNarrowing && (leafType.isBoundParameterizedType() || leafType.isTypeVariable())) {
330
					this.bits |= UnsafeCast;
331
					return true;
332
				}
333
				break;
334
			case Binding.TYPE_PARAMETER :
309
				this.bits |= UnsafeCast;
335
				this.bits |= UnsafeCast;
310
				return true;
336
				return true;				
311
			}
312
		}
337
		}
313
		if (!isNarrowing && match == this.resolvedType.leafComponentType()) { // do not tag as unnecessary when recursing through upper bounds
338
		if (!isNarrowing && match == this.resolvedType.leafComponentType()) { // do not tag as unnecessary when recursing through upper bounds
314
			tagAsUnnecessaryCast(scope, castType);
339
			tagAsUnnecessaryCast(scope, castType);

Return to bug 165143