8345944: JEP 492: extending local class in a different static context should not be allowed

8345953: JEP 492: instantiating local classes in a different static context should not be allowed

Reviewed-by: vromero
This commit is contained in:
Maurizio Cimadamore 2024-12-12 10:49:35 +00:00
parent 68aa4d44ff
commit 0ad64234e2
6 changed files with 271 additions and 9 deletions

View File

@ -2587,10 +2587,6 @@ public class Attr extends JCTree.Visitor {
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 class Attr extends JCTree.Visitor {
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 class Attr extends JCTree.Visitor {
}
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())) {

View File

@ -3834,7 +3834,7 @@ public class Resolve {
*/
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 @@ public class Resolve {
if (isStatic(env1)) staticOnly = true;
env1 = env1.outer;
}
return methodNotFound;
return owner.kind == MTH ?
methodNotFound :
varNotFound;
}
/**

View File

@ -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 LocalFreeVarStaticInstantiate {
};
}
};
// 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
};
}
}
}

View File

@ -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

View File

@ -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(); }
}
};
}
}
}

View File

@ -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