diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java index 62f7c15a95f85..2c3a79650b49c 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java @@ -2587,10 +2587,6 @@ public void visitApply(JCMethodInvocation tree) { chk.checkRefType(qualifier.pos(), attribExpr(qualifier, localEnv, encl)); - } else if (methName == names._super) { - // qualifier omitted; check for existence - // of an appropriate implicit qualifier. - checkNewInnerClass(tree.meth.pos(), localEnv, site, true); } } else if (tree.meth.hasTag(SELECT)) { log.error(tree.meth.pos(), @@ -2598,6 +2594,15 @@ public void visitApply(JCMethodInvocation tree) { attribExpr(((JCFieldAccess) tree.meth).selected, localEnv, site); } + if (tree.meth.hasTag(IDENT)) { + // non-qualified super(...) call; check whether explicit constructor + // invocation is well-formed. If the super class is an inner class, + // make sure that an appropriate implicit qualifier exists. If the super + // class is a local class, make sure that the current class is defined + // in the same context as the local class. + checkNewInnerClass(tree.meth.pos(), localEnv, site, true); + } + // if we're calling a java.lang.Enum constructor, // prefix the implicit String and int parameters if (site.tsym == syms.enumSym) @@ -3065,7 +3070,7 @@ public void report(DiagnosticPosition _unused, JCDiagnostic details) { } void checkNewInnerClass(DiagnosticPosition pos, Env<AttrContext> env, Type type, boolean isSuper) { - boolean isLocal = type.tsym.owner.kind == MTH; + boolean isLocal = type.tsym.owner.kind == VAR || type.tsym.owner.kind == MTH; if ((type.tsym.flags() & (INTERFACE | ENUM | RECORD)) != 0 || (!isLocal && !type.tsym.isInner()) || (isSuper && env.enclClass.sym.isAnonymous())) { diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java index 43a0c61a069bd..855b8a4b23475 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -3834,7 +3834,7 @@ Symbol findSelfContaining(DiagnosticPosition pos, */ Symbol findLocalClassOwner(Env<AttrContext> env, TypeSymbol c) { Symbol owner = c.owner; - Assert.check(owner.kind == MTH); + Assert.check(owner.kind == MTH || owner.kind == VAR); Env<AttrContext> env1 = env; boolean staticOnly = false; while (env1.outer != null) { @@ -3846,7 +3846,9 @@ Symbol findLocalClassOwner(Env<AttrContext> env, TypeSymbol c) { if (isStatic(env1)) staticOnly = true; env1 = env1.outer; } - return methodNotFound; + return owner.kind == MTH ? + methodNotFound : + varNotFound; } /** diff --git a/test/langtools/tools/javac/LocalFreeVarStaticInstantiate.java b/test/langtools/tools/javac/LocalFreeVarStaticInstantiate.java index 39b419c694ae2..09d33573da5b5 100644 --- a/test/langtools/tools/javac/LocalFreeVarStaticInstantiate.java +++ b/test/langtools/tools/javac/LocalFreeVarStaticInstantiate.java @@ -1,6 +1,6 @@ /* * @test /nodynamiccopyright/ - * @bug 8322882 + * @bug 8322882 8345953 * @summary Disallow attempts to access a free variable proxy field from a static method * @compile/fail/ref=LocalFreeVarStaticInstantiate.out -XDrawDiagnostics LocalFreeVarStaticInstantiate.java */ @@ -41,4 +41,61 @@ class Local { }; } }; + + // local class in switch + static Object bar = switch (foo) { + case Runnable r -> { + Object there = ""; + class Local { + { + there.hashCode(); + } + + static { + new Local(); // can't get there from here + } + + static Runnable r = () -> { + new Local(); // can't get there from here + }; + } + yield r; + } + }; + + // local class in instance init + { + Object there = ""; + class Local { + { + there.hashCode(); + } + + static { + new Local(); // can't get there from here + } + + static Runnable r = () -> { + new Local(); // can't get there from here + }; + } + } + + // local class in static init + static { + Object there = ""; + class Local { + { + there.hashCode(); + } + + static { + new Local(); // can't get there from here + } + + static Runnable r = () -> { + new Local(); // can't get there from here + }; + } + } } diff --git a/test/langtools/tools/javac/LocalFreeVarStaticInstantiate.out b/test/langtools/tools/javac/LocalFreeVarStaticInstantiate.out index 50e913083b074..9c26cf4a52702 100644 --- a/test/langtools/tools/javac/LocalFreeVarStaticInstantiate.out +++ b/test/langtools/tools/javac/LocalFreeVarStaticInstantiate.out @@ -2,4 +2,10 @@ LocalFreeVarStaticInstantiate.java:18:17: compiler.err.local.cant.be.inst.static LocalFreeVarStaticInstantiate.java:22:17: compiler.err.local.cant.be.inst.static: kindname.class, Local LocalFreeVarStaticInstantiate.java:36:17: compiler.err.local.cant.be.inst.static: kindname.class, Local LocalFreeVarStaticInstantiate.java:40:17: compiler.err.local.cant.be.inst.static: kindname.class, Local -4 errors +LocalFreeVarStaticInstantiate.java:55:21: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticInstantiate.java:59:21: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticInstantiate.java:75:17: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticInstantiate.java:79:17: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticInstantiate.java:93:17: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticInstantiate.java:97:17: compiler.err.local.cant.be.inst.static: kindname.class, Local +10 errors diff --git a/test/langtools/tools/javac/LocalFreeVarStaticSuper.java b/test/langtools/tools/javac/LocalFreeVarStaticSuper.java new file mode 100644 index 0000000000000..332eb239e35fa --- /dev/null +++ b/test/langtools/tools/javac/LocalFreeVarStaticSuper.java @@ -0,0 +1,161 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8345944 + * @summary JEP 492: extending local class in a different static context should not be allowed + * @compile/fail/ref=LocalFreeVarStaticSuper.out -XDrawDiagnostics LocalFreeVarStaticSuper.java + */ + +class LocalFreeVarStaticSuper { + + // local class in method + static void foo(Object there) { + class Local { + { + there.hashCode(); + } + + static { + class Sub1 extends Local { } + class Sub2 extends Local { + Sub2() { } + } + class Sub3 extends Local { + Sub3() { super(); } + } + } + + static Runnable r = () -> { + class Sub1 extends Local { } + class Sub2 extends Local { + Sub2() { } + } + class Sub3 extends Local { + Sub3() { super(); } + } + }; + } + } + + // local class in lambda + static Runnable foo = () -> { + Object there = ""; + class Local { + { + there.hashCode(); + } + + static { + class Sub1 extends Local { } + class Sub2 extends Local { + Sub2() { } + } + class Sub3 extends Local { + Sub3() { super(); } + } + } + + static Runnable r = () -> { + class Sub1 extends Local { } + class Sub2 extends Local { + Sub2() { } + } + class Sub3 extends Local { + Sub3() { super(); } + } + }; + } + }; + + // local class in switch + static Object bar = switch (foo) { + case Runnable r -> { + Object there = ""; + class Local { + { + there.hashCode(); + } + + static { + class Sub1 extends Local { } + class Sub2 extends Local { + Sub2() { } + } + class Sub3 extends Local { + Sub3() { super(); } + } + } + + static Runnable r = () -> { + class Sub1 extends Local { } + class Sub2 extends Local { + Sub2() { } + } + class Sub3 extends Local { + Sub3() { super(); } + } + }; + } + yield r; + } + }; + + // local class in instance init + { + Object there = ""; + class Local { + { + there.hashCode(); + } + + static { + class Sub1 extends Local { } + class Sub2 extends Local { + Sub2() { } + } + class Sub3 extends Local { + Sub3() { super(); } + } + } + + static Runnable r = () -> { + class Sub1 extends Local { } + class Sub2 extends Local { + Sub2() { } + } + class Sub3 extends Local { + Sub3() { super(); } + } + }; + } + } + + // local class in static init + static { + Object there = ""; + class Local { + { + there.hashCode(); + } + + static { + class Sub1 extends Local { } + class Sub2 extends Local { + Sub2() { } + } + class Sub3 extends Local { + Sub3() { super(); } + } + } + + static Runnable r = () -> { + class Sub1 extends Local { } + class Sub2 extends Local { + Sub2() { } + } + class Sub3 extends Local { + Sub3() { super(); } + } + }; + } + } +} diff --git a/test/langtools/tools/javac/LocalFreeVarStaticSuper.out b/test/langtools/tools/javac/LocalFreeVarStaticSuper.out new file mode 100644 index 0000000000000..d85451337bd82 --- /dev/null +++ b/test/langtools/tools/javac/LocalFreeVarStaticSuper.out @@ -0,0 +1,31 @@ +LocalFreeVarStaticSuper.java:18:17: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticSuper.java:20:28: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticSuper.java:23:30: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticSuper.java:28:17: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticSuper.java:30:28: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticSuper.java:33:30: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticSuper.java:48:17: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticSuper.java:50:28: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticSuper.java:53:30: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticSuper.java:58:17: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticSuper.java:60:28: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticSuper.java:63:30: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticSuper.java:79:21: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticSuper.java:81:32: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticSuper.java:84:34: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticSuper.java:89:21: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticSuper.java:91:32: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticSuper.java:94:34: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticSuper.java:111:17: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticSuper.java:113:28: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticSuper.java:116:30: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticSuper.java:121:17: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticSuper.java:123:28: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticSuper.java:126:30: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticSuper.java:141:17: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticSuper.java:143:28: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticSuper.java:146:30: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticSuper.java:151:17: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticSuper.java:153:28: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticSuper.java:156:30: compiler.err.local.cant.be.inst.static: kindname.class, Local +30 errors