Community
Participate
Working Groups
Version: 2.1.2 Build id: 200311030802 The following illegal code is accepted by the compiler: class Conv1 { public static void main(String[] args) { A a = null; B b = (B) a; //COMPILER ERROR } } interface A { void doSomething(); } interface B { int doSomething(); } The error from Sun's JDK 1.4.2 is C:\orpe\jtst>c:\j2sdk1.4.2_02\bin\javac Conv1.java Conv1.java:4: types A and B are incompatible; both define doSomething(), but with different return type B b = (B) a; //COMPILER ERROR ^ 1 error cf. java bug 4028359 http://developer.java.sun.com/developer/bugParade/bugs/4028359.html
This is also a bug in latest 3.0 stream.
The code: if (Scope.compareTypes(castType, expressionType) == NotRelated) { MethodBinding[] castTypeMethods = ((ReferenceBinding) castType).methods(); MethodBinding[] expressionTypeMethods = ((ReferenceBinding) expressionType).methods(); 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) && (castTypeMethods[i].selector == expressionTypeMethods[j].selector) && castTypeMethods[i].areParametersEqual(expressionTypeMethods[j])) { scope.problemReporter().typeCastError(this, castType, expressionType); } } } Looks suspicious. The cast is invalid only if the methods from one type are not compatible with the methods from the other type. If the two types are not related, then this is an error case, isn't it?
The problem comes from == between two char[]. Fixed and released in HEAD. I will close it as soon as I added some regression tests. Classes changed: EqualExpression CastExpression InstanceofExpression SyntheticMethodAccessBinding
Fixed and released in HEAD. Regression tests added for the three cases. Candidate for M5.
I will backport to 2.1.x
Backported to 2.1. maintenance stream.
Verified in 200311201600.
Verified for 2.1.3 (M20040225)
This issue is fixed in Release 3.0.0 (build ID: I200406251208), but I'm opening it again because a very similar example still doesn't work: public class Test { interface A { void doSomething(); } interface B { int doSomething(); } interface C extends B { } public static void main(String[] args) { A a = null; C c = (C)a; //COMPILER ERROR } } Again, the above illegal code is accepted by the compiler
Philippe, I added a check for the method length, but I think we should also get the methods from the super interfaces when we retrieve the method for Test.C.
I take it back. The check on the length is completely wrong. We need to collect methods through all superinterfaces to find out if the cast is legal or not.
Created attachment 14078 [details] Apply on HEAD Here is a patch that fixes this issue. I collect all methods for all super interfaces before I check if the methods are compatible. Before only the first level was done leading to the second bug.
Philippe, Could you please review this fix?
No regression in the JCK tests with this fix. All our tests are also green.
Fixed and released in HEAD. Regression tests added. Philippe, please review the change in the Expression class. The tests are valid so I can safely release them. We might want to backport them to 2.1.x and 3.0.x streams.
Verified in I200409212000.