Skip to content

Commit d80d478

Browse files
archiecobbsVicente Romero
authored andcommitted
8328649: Disallow enclosing instances for local classes in constructor prologues
Reviewed-by: vromero
1 parent 83eba86 commit d80d478

File tree

5 files changed

+40
-33
lines changed

5 files changed

+40
-33
lines changed

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -954,10 +954,10 @@ public void visitClassDef(JCClassDecl tree) {
954954
// make sure class has been completed:
955955
c.complete();
956956

957-
// If this class appears as an anonymous class in a constructor
958-
// prologue, disable implicit outer instance from being passed.
959-
// (This would be an illegal access to "this before super").
960-
if (ctorProloguePrev && env.tree.hasTag(NEWCLASS)) {
957+
// If a class declaration appears in a constructor prologue,
958+
// that means it's either a local class or an anonymous class.
959+
// Either way, there is no immediately enclosing instance.
960+
if (ctorProloguePrev) {
961961
c.flags_field |= NOOUTERTHIS;
962962
}
963963
attribClass(tree.pos(), c);

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1843,7 +1843,6 @@ JCExpression makeOuterThis(DiagnosticPosition pos, TypeSymbol c) {
18431843
List<VarSymbol> ots = outerThisStack;
18441844
if (ots.isEmpty()) {
18451845
log.error(pos, Errors.NoEnclInstanceOfTypeInScope(c));
1846-
Assert.error();
18471846
return makeNull();
18481847
}
18491848
VarSymbol ot = ots.head;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* @test /nodynamiccopyright/
3+
* @bug 8328649
4+
* @summary Verify local classes in constructor prologues don't have enclosing instances
5+
* @compile/fail/ref=LocalClassCtorPrologue.out -XDrawDiagnostics LocalClassCtorPrologue.java
6+
* @enablePreview
7+
*/
8+
9+
class LocalClassCtorPrologue {
10+
11+
int x;
12+
13+
LocalClassCtorPrologue() {
14+
class Local {
15+
{
16+
x++; // this should fail
17+
}
18+
}
19+
super();
20+
}
21+
22+
public class Inner {
23+
public Inner() {
24+
class Local {
25+
{
26+
x++; // this should work
27+
}
28+
};
29+
super();
30+
}
31+
}
32+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
LocalClassCtorPrologue.java:16:17: compiler.err.no.encl.instance.of.type.in.scope: LocalClassCtorPrologue
2+
- compiler.note.preview.filename: LocalClassCtorPrologue.java, DEFAULT
3+
- compiler.note.preview.recompile
4+
1 error

test/langtools/tools/javac/SuperInit/SuperInitGood.java

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -407,32 +407,6 @@ public int hashCode() {
407407
}
408408
}
409409

410-
// local class declared before super(), but not used until after super()
411-
public static class Test20 {
412-
public Test20() {
413-
class Foo {
414-
Foo() {
415-
Test20.this.hashCode();
416-
}
417-
}
418-
super();
419-
new Foo();
420-
}
421-
}
422-
423-
// local class inside super() parameter list
424-
public static class Test21 extends AtomicReference<Object> {
425-
private int x;
426-
public Test21() {
427-
super(switch ("foo".hashCode()) {
428-
default -> {
429-
class Nested {{ System.out.println(x); }} // class is NOT instantiated - OK
430-
yield "bar";
431-
}
432-
});
433-
}
434-
}
435-
436410
public static void main(String[] args) {
437411
new Test0();
438412
new Test1();
@@ -474,7 +448,5 @@ public static void main(String[] args) {
474448
assert false : "unexpected exception: " + e;
475449
}
476450
new Test19(123);
477-
new Test20();
478-
new Test21();
479451
}
480452
}

0 commit comments

Comments
 (0)