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 07f2a742bcbcb..d88180bb15c77 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 @@ -3843,12 +3843,15 @@ Symbol findLocalClassOwner(Env env, TypeSymbol c) { Env env1 = env; boolean staticOnly = false; while (env1.outer != null) { + // If the local class is defined inside a static method, and the instance creation expression + // occurs in that same method, the creation occurs (technically) inside a static context, but that's ok. if (env1.info.scope.owner == owner) { return (staticOnly) ? new BadLocalClassCreation(c) : owner; + } else if (isStatic(env1) || env1.enclClass.sym.isStatic()) { + staticOnly = true; } - if (isStatic(env1)) staticOnly = true; env1 = env1.outer; } return owner.kind == MTH ? diff --git a/test/langtools/tools/javac/SuperInit/NewLocalNotInInner.java b/test/langtools/tools/javac/SuperInit/NewLocalNotInInner.java new file mode 100644 index 0000000000000..8a69bc37667f1 --- /dev/null +++ b/test/langtools/tools/javac/SuperInit/NewLocalNotInInner.java @@ -0,0 +1,72 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8373570 + * @summary Javac stack overflow on method-local class with nested record referring to enclosing type + * @compile/fail/ref=NewLocalNotInInner.out -XDrawDiagnostics NewLocalNotInInner.java + */ +class NewLocalNotInInner { + void m() { + class Local { + static class Foo { + void m() { + new Local(); // error + } + } + } + } + + void m_anon() { + class Local { + static class Foo { + void m() { + new Local() { }; // error + } + } + } + } + + void m_record() { + class Local { + record Foo() { + void m() { + new Local(); // error + } + } + } + } + + void m_intf() { + class Local { + interface Foo { + default void m() { + new Local(); // error + } + } + } + } + + void sup() { + class Local { + static class Foo { + void m() { + class Sub extends Local { }; // error + new Sub(); + } + } + } + } + + static void staticLocal() { + class Local { } + new Local(); // ok + } + + static void staticLocalFromAnon() { + class Local { } + new Object() { + Local local() { + return new Local(); // ok + } + }; + } +} diff --git a/test/langtools/tools/javac/SuperInit/NewLocalNotInInner.out b/test/langtools/tools/javac/SuperInit/NewLocalNotInInner.out new file mode 100644 index 0000000000000..dd816f2ab0e0a --- /dev/null +++ b/test/langtools/tools/javac/SuperInit/NewLocalNotInInner.out @@ -0,0 +1,6 @@ +NewLocalNotInInner.java:12:21: compiler.err.local.cant.be.inst.static: kindname.class, Local +NewLocalNotInInner.java:22:21: compiler.err.local.cant.be.inst.static: kindname.class, Local +NewLocalNotInInner.java:32:21: compiler.err.local.cant.be.inst.static: kindname.class, Local +NewLocalNotInInner.java:42:21: compiler.err.local.cant.be.inst.static: kindname.class, Local +NewLocalNotInInner.java:52:21: compiler.err.local.cant.be.inst.static: kindname.class, Local +5 errors