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.
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.
- duplicates
-
JDK-4836078 Mantis javac thinks equals(Object) can be abstract
- Closed
- relates to
-
JDK-4275601 Compiler thinks equals(Object) is abstract
- Resolved
-
JDK-4761586 overload resolution for super.method() when intf overrider inherited from Object
- Resolved
-
JDK-4839284 Javac fails to compile valid source code.
- Resolved