8328649: Disallow enclosing instances for local classes in constructor prologues

Reviewed-by: vromero
This commit is contained in:
Archie Cobbs 2024-04-04 21:13:49 +00:00 committed by Vicente Romero
parent 83eba863fe
commit d80d478182
5 changed files with 40 additions and 33 deletions

View File

@ -954,10 +954,10 @@ public class Attr extends JCTree.Visitor {
// make sure class has been completed:
c.complete();
// If this class appears as an anonymous class in a constructor
// prologue, disable implicit outer instance from being passed.
// (This would be an illegal access to "this before super").
if (ctorProloguePrev && env.tree.hasTag(NEWCLASS)) {
// If a class declaration appears in a constructor prologue,
// that means it's either a local class or an anonymous class.
// Either way, there is no immediately enclosing instance.
if (ctorProloguePrev) {
c.flags_field |= NOOUTERTHIS;
}
attribClass(tree.pos(), c);

View File

@ -1843,7 +1843,6 @@ public class Lower extends TreeTranslator {
List<VarSymbol> ots = outerThisStack;
if (ots.isEmpty()) {
log.error(pos, Errors.NoEnclInstanceOfTypeInScope(c));
Assert.error();
return makeNull();
}
VarSymbol ot = ots.head;

View File

@ -0,0 +1,32 @@
/*
* @test /nodynamiccopyright/
* @bug 8328649
* @summary Verify local classes in constructor prologues don't have enclosing instances
* @compile/fail/ref=LocalClassCtorPrologue.out -XDrawDiagnostics LocalClassCtorPrologue.java
* @enablePreview
*/
class LocalClassCtorPrologue {
int x;
LocalClassCtorPrologue() {
class Local {
{
x++; // this should fail
}
}
super();
}
public class Inner {
public Inner() {
class Local {
{
x++; // this should work
}
};
super();
}
}
}

View File

@ -0,0 +1,4 @@
LocalClassCtorPrologue.java:16:17: compiler.err.no.encl.instance.of.type.in.scope: LocalClassCtorPrologue
- compiler.note.preview.filename: LocalClassCtorPrologue.java, DEFAULT
- compiler.note.preview.recompile
1 error

View File

@ -407,32 +407,6 @@ public class SuperInitGood {
}
}
// local class declared before super(), but not used until after super()
public static class Test20 {
public Test20() {
class Foo {
Foo() {
Test20.this.hashCode();
}
}
super();
new Foo();
}
}
// local class inside super() parameter list
public static class Test21 extends AtomicReference<Object> {
private int x;
public Test21() {
super(switch ("foo".hashCode()) {
default -> {
class Nested {{ System.out.println(x); }} // class is NOT instantiated - OK
yield "bar";
}
});
}
}
public static void main(String[] args) {
new Test0();
new Test1();
@ -474,7 +448,5 @@ public class SuperInitGood {
assert false : "unexpected exception: " + e;
}
new Test19(123);
new Test20();
new Test21();
}
}