[lworld] RFR: 8367323: [lworld] javac is rejecting valid code after fix for JDK-8359370

Vicente Romero vromero at openjdk.org
Fri Sep 12 15:18:59 UTC 2025


On Thu, 11 Sep 2025 08:53:22 GMT, Maurizio Cimadamore <mcimadamore at openjdk.org> wrote:

>> Recent fix for [JDK-8359370](https://bugs.openjdk.org/browse/JDK-8359370) introduced a minor bug. This code should be accepted by javac:
>> 
>> class SuperClass<T> {
>>     public SuperClass(Object o) {}
>> }
>> 
>> class Sub<T> extends SuperClass<T> {
>>     public Sub() {
>>         super(new Object() {
>>             void foo() {
>>                 getClass();
>>             }
>>         });
>>     }
>> }
>> 
>> 
>> but it is currently rejected as the `getClass` invocation is considered to be an invocation of an instance method of class `Sub`
>
> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java line 1477:
> 
>> 1475:                  * the compiler
>> 1476:                  */
>> 1477:                 return sym.kind != MTH || !insideClassDef;
> 
> I think the "right" thing to do here seems to have to do with membership and whether the access is unqualified or not.
> 
> E.g. 
> * if we are in the prologue of `A`, and we see a call to `m()`, and `m()` is a member of `A`, then we should fail
> * if we are in a class `B` inside the prologue of `A`, and we see a call to `m()`, and `m()` is a member of `B`, then it should be ok
> * if we are in a class `B` inside the prologue of `A`, and we see a call to `m()`, and `m()` is a member of _both_ `B` and `A`, then it should be ok
> * if we are in a class `B` inside the prologue of `A`, and we see a call to `m()`, and `m()` is a member of `A` then it should fail
> 
> The problem seems to be that, by the time we hit the `isEarlyReference` method, we no longer know the "current class" -- so we always check membership against the "outer" class whose prologue we're inspecting.

I have updated the PR there is a test case that was failing before but now is passing:

class Test {
    public int xx;

    Test() {
        int i = new Test(){
            void foo() {
                System.err.println(xx);
            }
        }.xx;
        super();
    }
}

I think that it is correct that we accept this code as in both cases we are accessing the `xx` field inherited by the anonymous class

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

PR Review Comment: https://git.openjdk.org/valhalla/pull/1567#discussion_r2341885465


More information about the valhalla-dev mailing list