Skip to content

Commit

Permalink
Fix enclosing instance chain to take into account inaccessible enclos…
Browse files Browse the repository at this point in the history
…ing instances
  • Loading branch information
mcimadamore committed Jun 14, 2024
1 parent 7e82cce commit 3ea65cc
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ public Type erasure(Types types) {
public Type externalType(Types types) {
Type t = erasure(types);
if (name == name.table.names.init && owner.hasOuterInstance()) {
Type outerThisType = types.erasure(owner.type.getEnclosingType());
Type outerThisType = types.erasure(owner.innermostAccessibleEnclosingType());
return new MethodType(t.getParameterTypes().prepend(outerThisType),
t.getReturnType(),
t.getThrownTypes(),
Expand Down Expand Up @@ -506,7 +506,17 @@ public boolean isInner() {
*/
public boolean hasOuterInstance() {
return
type.getEnclosingType().hasTag(CLASS) && (flags() & (INTERFACE | ENUM | RECORD | NOOUTERTHIS)) == 0;
type.getEnclosingType().hasTag(CLASS) && (flags() & (INTERFACE | ENUM | RECORD)) == 0 &&
((flags() & NOOUTERTHIS) == 0 || type.getEnclosingType().tsym.hasOuterInstance());
}

public Type innermostAccessibleEnclosingType() {
Assert.check(enclClass().hasOuterInstance());
Type current = enclClass().type;
while ((current.tsym.flags() & NOOUTERTHIS) != 0) {
current = current.getEnclosingType();
}
return current.getEnclosingType();
}

/** The closest enclosing class of this symbol's declaration.
Expand Down
51 changes: 3 additions & 48 deletions src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java
Original file line number Diff line number Diff line change
Expand Up @@ -372,52 +372,7 @@ void visitSymbol(Symbol sym) {
}
}
}
if (sym.kind == VAR || sym.kind == MTH) {
if (outerThisStack.head != null &&
outerThisStack.head != sym)
visitSymbol(outerThisStack.head);
}
}

/** If tree refers to a class instance creation expression
* add all free variables of the freshly created class.
*/
public void visitNewClass(JCNewClass tree) {
ClassSymbol c = (ClassSymbol)tree.constructor.owner;
if (tree.encl == null &&
c.hasOuterInstance() &&
outerThisStack.head != null)
visitSymbol(outerThisStack.head);
super.visitNewClass(tree);
}

/** If tree refers to a qualified this or super expression
* for anything but the current class, add the outer this
* stack as a free variable.
*/
public void visitSelect(JCFieldAccess tree) {
if ((tree.name == names._this || tree.name == names._super) &&
tree.selected.type.tsym != clazz &&
outerThisStack.head != null)
visitSymbol(outerThisStack.head);
super.visitSelect(tree);
}

/** If tree refers to a superclass constructor call,
* add all free variables of the superclass.
*/
public void visitApply(JCMethodInvocation tree) {
if (TreeInfo.name(tree.meth) == names._super) {
Symbol constructor = TreeInfo.symbol(tree.meth);
ClassSymbol c = (ClassSymbol)constructor.owner;
if (c.hasOuterInstance() &&
!tree.meth.hasTag(SELECT) &&
outerThisStack.head != null)
visitSymbol(outerThisStack.head);
}
super.visitApply(tree);
}

}

ClassSymbol ownerToCopyFreeVarsFrom(ClassSymbol c) {
Expand Down Expand Up @@ -1591,7 +1546,7 @@ Name outerThisName(Type type, Symbol owner) {
}

private VarSymbol makeOuterThisVarSymbol(Symbol owner, long flags) {
Type target = types.erasure(owner.enclClass().type.getEnclosingType());
Type target = types.erasure(owner.innermostAccessibleEnclosingType());
// Set NOOUTERTHIS for all synthetic outer instance variables, and unset
// it when the variable is accessed. If the variable is never accessed,
// we skip creating an outer instance field and saving the constructor
Expand Down Expand Up @@ -3102,7 +3057,7 @@ public void visitNewClass(JCNewClass tree) {
thisArg.type = tree.encl.type;
} else if (c.isDirectlyOrIndirectlyLocal()) {
// local class
thisArg = makeThis(tree.pos(), c.type.getEnclosingType().tsym);
thisArg = makeThis(tree.pos(), c.innermostAccessibleEnclosingType().tsym);
} else {
// nested class
thisArg = makeOwnerThis(tree.pos(), c, false);
Expand Down Expand Up @@ -3308,7 +3263,7 @@ public void visitApply(JCMethodInvocation tree) {
((JCIdent) tree.meth).name = methName;
} else if (c.isDirectlyOrIndirectlyLocal() || methName == names._this){
// local class or this() call
thisArg = makeThis(tree.meth.pos(), c.type.getEnclosingType().tsym);
thisArg = makeThis(tree.meth.pos(), c.innermostAccessibleEnclosingType().tsym);
} else if (currentClass.isStatic()) {
// super() call from static nested class - invalid
log.error(tree.pos(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class LocalClassTest$1 -- anon
LocalClassTest$1.<init>(final this$0/*implicit*/, final j, final val$i/*synthetic*/)
class LocalClassTest$1CapturingLocal$1 -- anon
LocalClassTest$1CapturingLocal$1.<init>(final val$this$0/*synthetic*/, final val$val$i/*synthetic*/)
LocalClassTest$1CapturingLocal$1.<init>(final this$0/*implicit*/, final val$val$i/*synthetic*/)
LocalClassTest$1CapturingLocal$1.test()
class LocalClassTest$1CapturingLocal -- inner
LocalClassTest$1CapturingLocal.<init>(final this$0/*implicit*/, final j, final val$i/*synthetic*/)
Expand Down

0 comments on commit 3ea65cc

Please sign in to comment.