Bug 47074 - inability to detect invalid cast between interfaces
Summary: inability to detect invalid cast between interfaces
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 2.1.2   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.1 M2   Edit
Assignee: Olivier Thomann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-11-20 07:00 EST by Orjan Petersson CLA
Modified: 2004-09-23 06:04 EDT (History)
1 user (show)

See Also:


Attachments
Apply on HEAD (2.25 KB, application/octet-stream)
2004-08-19 14:10 EDT, Olivier Thomann CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Orjan Petersson CLA 2003-11-20 07:00:55 EST
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
Comment 1 Olivier Thomann CLA 2003-11-20 10:34:45 EST
This is also a bug in latest 3.0 stream.
Comment 2 Olivier Thomann CLA 2003-11-20 10:41:20 EST
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? 
Comment 3 Olivier Thomann CLA 2003-11-20 11:09:12 EST
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
Comment 4 Olivier Thomann CLA 2003-11-20 11:19:34 EST
Fixed and released in HEAD.
Regression tests added for the three cases.
Candidate for M5.
Comment 5 Olivier Thomann CLA 2003-11-20 11:25:41 EST
I will backport to 2.1.x
Comment 6 Olivier Thomann CLA 2003-11-20 11:50:52 EST
Backported to 2.1. maintenance stream.
Comment 7 Olivier Thomann CLA 2003-11-20 20:55:48 EST
Verified in 200311201600.
Comment 8 David Audel CLA 2004-03-01 12:06:35 EST
Verified for 2.1.3 (M20040225)
Comment 9 Eduardo Fuentetaja CLA 2004-08-19 03:55:33 EDT
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
Comment 10 Olivier Thomann CLA 2004-08-19 11:52:29 EDT
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.
Comment 11 Olivier Thomann CLA 2004-08-19 13:57:13 EDT
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.
Comment 12 Olivier Thomann CLA 2004-08-19 14:10:15 EDT
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.
Comment 13 Olivier Thomann CLA 2004-08-19 14:10:47 EDT
Philippe,

Could you please review this fix?
Comment 14 Olivier Thomann CLA 2004-08-20 15:04:41 EDT
No regression in the JCK tests with this fix. All our tests are also green.
Comment 15 Olivier Thomann CLA 2004-08-23 16:05:54 EDT
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.
Comment 16 David Audel CLA 2004-09-23 06:04:26 EDT
Verified in I200409212000.