Skip to content

Commit

Permalink
8328649: Disallow enclosing instances for local classes in constructo…
Browse files Browse the repository at this point in the history
…r prologues

Reviewed-by: vromero
  • Loading branch information
archiecobbs authored and Vicente Romero committed Apr 4, 2024
1 parent 83eba86 commit d80d478
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -954,10 +954,10 @@ public void visitClassDef(JCClassDecl tree) {
// 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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1843,7 +1843,6 @@ JCExpression makeOuterThis(DiagnosticPosition pos, TypeSymbol c) {
List<VarSymbol> ots = outerThisStack;
if (ots.isEmpty()) {
log.error(pos, Errors.NoEnclInstanceOfTypeInScope(c));
Assert.error();
return makeNull();
}
VarSymbol ot = ots.head;
Expand Down
32 changes: 32 additions & 0 deletions test/langtools/tools/javac/LocalClassCtorPrologue.java
Original file line number Diff line number Diff line change
@@ -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();
}
}
}
4 changes: 4 additions & 0 deletions test/langtools/tools/javac/LocalClassCtorPrologue.out
Original file line number Diff line number Diff line change
@@ -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
28 changes: 0 additions & 28 deletions test/langtools/tools/javac/SuperInit/SuperInitGood.java
Original file line number Diff line number Diff line change
Expand Up @@ -407,32 +407,6 @@ public int hashCode() {
}
}

// 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();
Expand Down Expand Up @@ -474,7 +448,5 @@ public static void main(String[] args) {
assert false : "unexpected exception: " + e;
}
new Test19(123);
new Test20();
new Test21();
}
}

1 comment on commit d80d478

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.