JDK-8189335: NPE in Lower due to class name clash

B. Blaser bsrbnd at gmail.com
Sun Feb 18 23:42:05 UTC 2018


Hi,

As explained in JDK-8189335, the following example crashes javac with
a NPE in Lower:

class R {
    private class R$1 {}
    void f() {
        new R$1();
    }
}
class R$1 {}

This seems to be due to the fact that javac wrongly concludes that the
constructor of 'R$1' needs private access and then generates an
anonymous class 'R$1' (see Lower.accessConstructor()) which conflicts
with the top level class using the same name.

The following fix gives access to inner class constructors the same
way as for local class constructors (needs to be well tested).

What do you think?

Thanks,
Bernard


diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java
b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java
@@ -1008,7 +1008,7 @@
     boolean needsPrivateAccess(Symbol sym) {
         if ((sym.flags() & PRIVATE) == 0 || sym.owner == currentClass) {
             return false;
-        } else if (sym.name == names.init && sym.owner.isLocal()) {
+        } else if (sym.name == names.init && (sym.owner.isLocal() ||
sym.owner.isEnclosedBy(currentClass))) {
             // private constructor in local class: relax protection
             sym.flags_field &= ~PRIVATE;
             return false;


More information about the compiler-dev mailing list