Buggy code:
} return checkCastTypesCompatibility ( scope , castType , ( ( TypeVariableBinding ) ( expressionType ) ) . upperBound ( ) , expression ) ; case Binding . WILDCARD_TYPE : case Binding . INTERSECTION_TYPE : match = expressionType . findSuperTypeOriginatingFrom ( castType ) ; if ( match != null ) { return checkUnsafeCast ( scope , castType , expressionType , match , false ) ; } return checkCastTypesCompatibility ( scope , castType , ( ( WildcardBinding ) ( expressionType ) ) . bound , expression ) ; default : if ( expressionType . isInterface ( ) ) { switch ( castType . kind ( ) ) { case Binding . ARRAY_TYPE : switch ( expressionType . id ) { case TypeIds . T_JavaLangCloneable : case TypeIds . T_JavaIoSerializable : tagAsNeedCheckCast ( ) ; return true ; default : return false ; } case Binding . TYPE_PARAMETER : match = expressionType . findSuperTypeOriginatingFrom ( castType ) ; if ( match == null ) { checkUnsafeCast ( scope , castType , expressionType , null , true ) ; } return checkCastTypesCompatibility ( scope , ( ( TypeVariableBinding ) ( castType ) ) . upperBound ( ) , expressionType , expression ) ; default : if ( castType . isInterface ( ) ) { ReferenceBinding interfaceType = ( ( ReferenceBinding ) ( expressionType ) ) ; match = interfaceType . findSuperTypeOriginatingFrom ( castType ) ; if ( match != null ) { return checkUnsafeCast ( scope , castType , interfaceType , match , false ) ; } tagAsNeedCheckCast ( ) ; match = castType . findSuperTypeOriginatingFrom ( interfaceType ) ; if ( match != null ) { return checkUnsafeCast ( scope , castType , interfaceType , match , true ) ; } if ( use15specifics ) { checkUnsafeCast ( scope , castType , expressionType , null , true ) ; if ( interfaceType . hasIncompatibleSuperType ( ( ( ReferenceBinding ) ( castType ) ) ) ) return false ; } else { MethodBinding [ ] castTypeMethods = getAllInheritedMethods ( ( ( ReferenceBinding ) ( castType ) ) ) ; MethodBinding [ ] expressionTypeMethods = getAllInheritedMethods ( ( ( ReferenceBinding ) ( expressionType ) ) ) ; int exprMethodsLength = expressionTypeMethods . length ; for ( int i = 0 , castMethodsLength = castTypeMethods . length ; i < castMethodsLength ; i ++ ) { for ( int j = 0 ; j < exprMethodsLength ; j ++ ) { if ( ( ( ( castTypeMethods [ i ] . returnType ) != ( expressionTypeMethods [ j ] . returnType ) ) && ( CharOperation . equals ( castTypeMethods [ i ] . selector , expressionTypeMethods [ j ] . selector ) ) ) && ( castTypeMethods [ i ] . areParametersEqual ( expressionTypeMethods [ j ] ) ) ) { return false ; } } } } return true ; } else { if ( ( castType . id ) == ( TypeIds . T_JavaLangObject ) ) { tagAsUnnecessaryCast ( scope , castType ) ; return true ; } tagAsNeedCheckCast ( ) ; match = castType . findSuperTypeOriginatingFrom ( expressionType ) ; if ( match != null ) { return checkUnsafeCast ( scope , castType , expressionType , match , true ) ; } if ( ( ( ReferenceBinding ) ( castType ) ) . isFinal ( ) ) { return false ; } if ( use15specifics ) { checkUnsafeCast ( scope , castType , expressionType , null , true ) ; if ( ( ( ReferenceBinding ) ( castType ) ) . hasIncompatibleSuperType ( ( ( ReferenceBinding ) ( expressionType ) ) ) ) { return false ; } } return true ; } } } else { switch ( castType . kind ( ) ) { case Binding . ARRAY_TYPE : if ( ( expressionType . id ) == ( TypeIds . T_JavaLangObject ) ) { if ( use15specifics ) checkUnsafeCast ( scope , castType , expressionType , expressionType , true ) ; tagAsNeedCheckCast ( ) ; return true ; } return false ; case Binding . TYPE_PARAMETER : match = expressionType . findSuperTypeOriginatingFrom ( castType ) ; if ( match == null ) { <START_BUG> checkUnsafeCast ( scope , castType , expressionType , match , true ) ; <END_BUG> } return checkCastTypesCompatibility ( scope , ( ( TypeVariableBinding ) ( castType ) ) . upperBound ( ) , expressionType , expression ) ; default : if ( castType . isInterface ( ) ) { ReferenceBinding refExprType = ( ( ReferenceBinding ) ( expressionType ) ) ; match = refExprType . findSuperTypeOriginatingFrom ( castType ) ; if ( match != null ) { return checkUnsafeCast ( scope , castType , expressionType , match , false ) ; } if ( refExprType . isFinal ( ) ) { return false ; } tagAsNeedCheckCast ( ) ; match = castType . findSuperTypeOriginatingFrom ( expressionType ) ; if ( match != null ) { return checkUnsafeCast ( scope , castType , expressionType , match , true ) ; } if ( use15specifics ) { checkUnsafeCast ( scope , castType , expressionType , null , true ) ; if ( refExprType . hasIncompatibleSuperType ( ( ( ReferenceBinding ) ( castType ) ) ) ) return false ; } return true ; } else { match = expressionType . findSuperTypeOriginatingFrom ( castType ) ; if ( match != null ) { if ( ( expression != null ) && ( ( castType . id ) == ( TypeIds . T_JavaLangString ) ) ) this . constant = expression . constant ; return checkUnsafeCast ( scope , castType , expressionType , match , false ) ; } match = castType . findSuperTypeOriginatingFrom ( expressionType ) ; if ( match != null ) { tagAsNeedCheckCast ( ) ; return checkUnsafeCast ( scope , castType , expressionType , match , true ) ; } return false ; } } } } }

Fix:
checkUnsafeCast ( scope , castType , expressionType , null , true ) ;