8334252: Verifier error for lambda declared in early construction context

Reviewed-by: mcimadamore
This commit is contained in:
Archie Cobbs 2024-06-14 14:53:05 +00:00 committed by Vicente Romero
parent b5212d7bfe
commit dae0bda9d0
2 changed files with 57 additions and 13 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -1239,7 +1239,7 @@ public class LambdaToMethod extends TreeTranslator {
private int lambdaCount = 0;
/**
* List of types undergoing construction via explicit constructor chaining.
* List of types undergoing construction, i.e., in an early construction context.
*/
private List<ClassSymbol> typesUnderConstruction;
@ -1280,15 +1280,10 @@ public class LambdaToMethod extends TreeTranslator {
@Override
public void visitApply(JCMethodInvocation tree) {
List<ClassSymbol> previousNascentTypes = typesUnderConstruction;
try {
Name methName = TreeInfo.name(tree.meth);
if (methName == names._this || methName == names._super) {
typesUnderConstruction = typesUnderConstruction.prepend(currentClass());
}
super.visitApply(tree);
} finally {
typesUnderConstruction = previousNascentTypes;
super.visitApply(tree);
if (TreeInfo.isConstructorCall(tree)) {
Assert.check(typesUnderConstruction.head == currentClass());
typesUnderConstruction = typesUnderConstruction.tail; // end of early construction context
}
}
// where
@ -1439,13 +1434,16 @@ public class LambdaToMethod extends TreeTranslator {
@Override
public void visitMethodDef(JCMethodDecl tree) {
List<ClassSymbol> prevTypesUnderConstruction = typesUnderConstruction;
List<Frame> prevStack = frameStack;
try {
if (TreeInfo.isConstructor(tree)) // start early construction context (Object() notwithstanding)
typesUnderConstruction = typesUnderConstruction.prepend(currentClass());
frameStack = frameStack.prepend(new Frame(tree));
super.visitMethodDef(tree);
}
finally {
} finally {
frameStack = prevStack;
typesUnderConstruction = prevTypesUnderConstruction;
}
}

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8194743
* @summary Test lambda declared in early construction context
* @enablePreview
*/
public class LambdaOuterCapture {
public class Inner {
public Inner() {
Runnable r = () -> System.out.println(LambdaOuterCapture.this);
this(r);
}
public Inner(Runnable r) {
}
}
public static void main(String[] args) {
new LambdaOuterCapture().new Inner();
}
}