RFR: 8337980: Javac allows invocation of an inherited instance method from a static method [v2]

Archie Cobbs acobbs at openjdk.org
Mon Oct 7 20:01:36 UTC 2024


On Mon, 7 Oct 2024 18:52:17 GMT, Maurizio Cimadamore <mcimadamore at openjdk.org> wrote:

>> By the time `mergeAbstracts` is called in the patched version of the code, the problem in the original version of the code has already occurred, i.e., the behavior of `mergeAbstracts` is not involved in how the bug happens. I verified that with those changes (`B::op` returning `Object` and `A::op` returning `String`) the verify error still occurs - even when you change the other constructor to `public C(String x)` (so that `B::op` would have an incompatible return value). I also verified that the modified example also works correctly with the PR applied.
>
> I guess what I'm asking is whether there's some way to alter the declaration of the problematic methods so that the early-constructor context error is not reported - this seems possible if mergeAbstracts merges info using the interface method as a base symbol?

I think I understand what you're saying (but apologies in advance if not :)

This particular bug can only occur in situations where an error should be reported, but you're wondering whether a similar situation could happen in valid code, which would mean the `AmbiguityError` is allowed to float downstream and possibly cause problems later... is that correct?

I believe that this can't happen because it always eventually gets resolved via `BasicLookupHelper.lookup()` which is used by `resolveMethod()`, `resolveQualifiedMethod()`, etc.

For example, this class:

public class D {

    public interface A {
        String op();
    }

    public abstract static class B {
        public abstract Object op();
    }

    public abstract static class C extends B implements A {

        public void foo(Object x) {
        }

        public void bar() {
            foo(op());
        }
    }
} 

compiles successfully, and `D.C.bar()` will invoke the `A.op` variant:

public abstract class D$C extends D$B implements D$A {
...
  public void bar();
    Code:
       0: aload_0
       1: aload_0
       2: invokevirtual #7                  // Method op:()Ljava/lang/String;
       5: invokevirtual #13                 // Method foo:(Ljava/lang/Object;)V
       8: return
}

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/20533#discussion_r1790799254


More information about the compiler-dev mailing list