-
Bug
-
Resolution: Fixed
-
P4
-
1.4.0, 1.4.1
-
None
-
tiger
-
generic, sparc
-
solaris_7, solaris_8
The following mirrors compiler bug report 4758654.
I recently fixed one bug in the compiler, and I got a regression
in a previously passing regression test. The previous test is for
bug 4275601. On looking at this more closely, it appears 4275601
may not have been a compiler bug after all, and we were wrong to
fix it.
Here's the situation:
interface A {
public boolean equals(Object o);
}
abstract class B implements A {}
abstract class C extends B {
boolean f(Object o) {
return super.equals(o);
}
}
Now, what of the call super.equals(o), it is an error (because it
is trying to call the abstract method A.equals) or is it not a
problem (because it is trying to call the concrete method
Object.equals)?
In order to answer this question, we have to perform the overload
resolution on the call super.equals(o). Both Object.equals and
A.equals are candidates, but in this case A.equals is more specific
because A is a subclass of Object. In fact A.equals is maximally
specific. So the call super.equals(o) refers to the abstract
method A.equals, and a diagnostic is required as per 15.12.3.
This leads me to the conclusion that 4275601 was never a compiler bug
after all and its fix should be withdrawn from the compiler. Note
that the "abstract" is a red herring in the declaration of B. The
analysis is unaffected by its presence. No version of javac has ever
correctly diagnosed this problem with the absence of that keyword.
It gets worse.
Every interface *implicitly* has a public method for every public method in
Object, so the test case can be simplified to this:
interface A {}
class B implements A {}
abstract class C extends B {
boolean f(Object o) {
return super.equals(o);
}
}
As it currently stands, this is required by JLS2 to be an error.
###@###.### 2002-10-10
I recently fixed one bug in the compiler, and I got a regression
in a previously passing regression test. The previous test is for
bug 4275601. On looking at this more closely, it appears 4275601
may not have been a compiler bug after all, and we were wrong to
fix it.
Here's the situation:
interface A {
public boolean equals(Object o);
}
abstract class B implements A {}
abstract class C extends B {
boolean f(Object o) {
return super.equals(o);
}
}
Now, what of the call super.equals(o), it is an error (because it
is trying to call the abstract method A.equals) or is it not a
problem (because it is trying to call the concrete method
Object.equals)?
In order to answer this question, we have to perform the overload
resolution on the call super.equals(o). Both Object.equals and
A.equals are candidates, but in this case A.equals is more specific
because A is a subclass of Object. In fact A.equals is maximally
specific. So the call super.equals(o) refers to the abstract
method A.equals, and a diagnostic is required as per 15.12.3.
This leads me to the conclusion that 4275601 was never a compiler bug
after all and its fix should be withdrawn from the compiler. Note
that the "abstract" is a red herring in the declaration of B. The
analysis is unaffected by its presence. No version of javac has ever
correctly diagnosed this problem with the absence of that keyword.
It gets worse.
Every interface *implicitly* has a public method for every public method in
Object, so the test case can be simplified to this:
interface A {}
class B implements A {}
abstract class C extends B {
boolean f(Object o) {
return super.equals(o);
}
}
As it currently stands, this is required by JLS2 to be an error.
###@###.### 2002-10-10
- duplicates
-
JDK-4814557 Failure to overload method causes subtyping to break
- Closed
- relates to
-
JDK-4839284 Javac fails to compile valid source code.
- Resolved
-
JDK-4758654 incorrect overload resolution for super.method() when inherited abstract
- Resolved