Skip to content

Commit

Permalink
8327695: [lworld] javac can generate incorrect code in inner class' c…
Browse files Browse the repository at this point in the history
…onstructors
  • Loading branch information
Vicente Romero committed Mar 18, 2024
1 parent 9b79f47 commit 5a13097
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 0 deletions.
15 changes: 15 additions & 0 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 @@ -190,6 +190,10 @@ protected Lower(Context context) {
*/
Map<Symbol, Symbol> lambdaTranslationMap = null;

/** A hash table mapping local classes to a set of outer this fields
*/
public Map<ClassSymbol, Set<JCExpression>> initializerOuterThis = new WeakHashMap<>();

/** A navigator class for assembling a mapping from local class symbols
* to class definition trees.
* There is only one case; all other cases simply traverse down the tree.
Expand Down Expand Up @@ -2958,6 +2962,17 @@ public void visitNewClass(JCNewClass tree) {
} else {
// nested class
thisArg = makeOwnerThis(tree.pos(), c, false);
if (currentMethodSym != null &&
((currentMethodSym.flags_field & (STATIC | BLOCK)) == BLOCK) &&
currentMethodSym.owner.isValueClass()) {
// instance initializer in a value class
Set<JCExpression> outerThisSet = initializerOuterThis.get(currentClass);
if (outerThisSet == null) {
outerThisSet = new HashSet<>();
}
outerThisSet.add(thisArg);
initializerOuterThis.put(currentClass, outerThisSet);
}
}
tree.args = tree.args.prepend(thisArg);
}
Expand Down
35 changes: 35 additions & 0 deletions src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,7 @@ void normalizeMethod(JCMethodDecl md, List<JCStatement> initCode, List<JCStateme
// We are seeing a constructor that has a super() call.
// Find the super() invocation and append the given initializer code.
if (md.sym.owner.isValueClass()) {
rewriteInitializersIfNeeded(md, initCode);
TreeInfo.mapSuperCalls(md.body, supercall -> make.Block(0, initCode.append(supercall).appendList(initBlocks)));
} else {
TreeInfo.mapSuperCalls(md.body, supercall -> make.Block(0, initCode.prepend(supercall)));
Expand All @@ -570,6 +571,40 @@ void normalizeMethod(JCMethodDecl md, List<JCStatement> initCode, List<JCStateme
}
}

void rewriteInitializersIfNeeded(JCMethodDecl md, List<JCStatement> initCode) {
if (lower.initializerOuterThis.containsKey(md.sym.owner)) {
InitializerVisitor initializerVisitor = new InitializerVisitor(md, lower.initializerOuterThis.get(md.sym.owner));
for (JCStatement init : initCode) {
initializerVisitor.scan(init);
}
}
}

class InitializerVisitor extends TreeScanner {
JCMethodDecl md;
Set<JCExpression> exprSet;

InitializerVisitor(JCMethodDecl md, Set<JCExpression> exprSet) {
this.md = md;
this.exprSet = exprSet;
}

@Override
public void visitTree(JCTree tree) {}

@Override
public void visitIdent(JCIdent tree) {
if (exprSet.contains(tree)) {
for (JCVariableDecl param: md.params) {
if (param.name == tree.name &&
((param.sym.flags_field & (MANDATED | NOOUTERTHIS)) == (MANDATED | NOOUTERTHIS))) {
tree.sym = param.sym;
}
}
}
}
}

/* ************************************************************************
* Traversal methods
*************************************************************************/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
/*
* @test
* @key randomness
* @bug 8327695
* @summary Test the basic value class implementation in C2.
* @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64")
* @modules java.base/jdk.internal.value
Expand Down

0 comments on commit 5a13097

Please sign in to comment.