diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java index eb99897ee59..c51b1cb2a7e 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java @@ -1196,6 +1196,18 @@ public class Lower extends TreeTranslator { } } + private boolean noClassDefIn(JCTree tree) { + var scanner = new TreeScanner() { + boolean noClassDef = true; + @Override + public void visitClassDef(JCClassDecl tree) { + noClassDef = false; + } + }; + scanner.scan(tree); + return scanner.noClassDef; + } + private void addPrunedInfo(JCTree tree) { List infoList = prunedTree.get(currentClass); infoList = (infoList == null) ? List.of(tree) : infoList.prepend(tree); @@ -3030,10 +3042,10 @@ public class Lower extends TreeTranslator { @Override public void visitConditional(JCConditional tree) { JCTree cond = tree.cond = translate(tree.cond, syms.booleanType); - if (isTrue(cond)) { + if (isTrue(cond) && noClassDefIn(tree.falsepart)) { result = convert(translate(tree.truepart, tree.type), tree.type); addPrunedInfo(cond); - } else if (isFalse(cond)) { + } else if (isFalse(cond) && noClassDefIn(tree.truepart)) { result = convert(translate(tree.falsepart, tree.type), tree.type); addPrunedInfo(cond); } else { @@ -3057,10 +3069,10 @@ public class Lower extends TreeTranslator { */ public void visitIf(JCIf tree) { JCTree cond = tree.cond = translate(tree.cond, syms.booleanType); - if (isTrue(cond)) { + if (isTrue(cond) && noClassDefIn(tree.elsepart)) { result = translate(tree.thenpart); addPrunedInfo(cond); - } else if (isFalse(cond)) { + } else if (isFalse(cond) && noClassDefIn(tree.thenpart)) { if (tree.elsepart != null) { result = translate(tree.elsepart); } else { diff --git a/test/langtools/tools/javac/6917288/GraphicalInstallerTest.java b/test/langtools/tools/javac/6917288/GraphicalInstallerTest.java index 8dfc0fabc44..3a5bd7d51b4 100644 --- a/test/langtools/tools/javac/6917288/GraphicalInstallerTest.java +++ b/test/langtools/tools/javac/6917288/GraphicalInstallerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2023, 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 @@ -47,6 +47,7 @@ public class GraphicalInstallerTest { } check(classes, + "GraphicalInstaller$1.class", "GraphicalInstaller$1X$1.class", "GraphicalInstaller$1X.class", "GraphicalInstaller$BackgroundInstaller.class", diff --git a/test/langtools/tools/javac/6917288/T6917288.java b/test/langtools/tools/javac/6917288/T6917288.java index 08b38449515..07c30e2d436 100644 --- a/test/langtools/tools/javac/6917288/T6917288.java +++ b/test/langtools/tools/javac/6917288/T6917288.java @@ -70,12 +70,15 @@ public class T6917288 { } switch (k) { + case NONE: + check(classesDir, "Test.class", "Test$Inner.class"); + break; case ALWAYS: case TRUE: check(classesDir, "Test.class", "Test$Inner.class", "Test$1.class"); break; default: - check(classesDir, "Test.class", "Test$Inner.class"); + check(classesDir, "Test.class", "Test$Inner.class", "Test$1.class"); } } diff --git a/test/langtools/tools/javac/7199823/InnerClassCannotBeVerified.java b/test/langtools/tools/javac/7199823/InnerClassCannotBeVerified.java deleted file mode 100644 index ae081a8c0a6..00000000000 --- a/test/langtools/tools/javac/7199823/InnerClassCannotBeVerified.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2012, 2018, 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 7199823 - * @summary javac generates inner class that can't be verified - * @modules java.base/jdk.internal.classfile - * java.base/jdk.internal.classfile.attribute - * java.base/jdk.internal.classfile.constantpool - * java.base/jdk.internal.classfile.instruction - * java.base/jdk.internal.classfile.components - * java.base/jdk.internal.classfile.impl - * @run main InnerClassCannotBeVerified - */ - -import java.nio.file.NoSuchFileException; -import java.util.Arrays; -import javax.tools.JavaFileObject; -import java.net.URI; -import javax.tools.SimpleJavaFileObject; -import javax.tools.ToolProvider; -import javax.tools.JavaCompiler; -import com.sun.source.util.JavacTask; -import jdk.internal.classfile.*; -import java.io.File; -import java.io.IOException; - -public class InnerClassCannotBeVerified { - - enum CompilationKind { - PRE_NESTMATES("-source", "10", "-target", "10"), - POST_NESTMATES(); - - String[] opts; - - CompilationKind(String... opts) { - this.opts = opts; - } - } - - private static final String errorMessage = - "Compile error while compiling the following source:\n"; - - public static void main(String... args) throws Exception { - new InnerClassCannotBeVerified().run(); - } - - void run() throws Exception { - for (CompilationKind ck : CompilationKind.values()) { - File file = new File("Test$1.class"); - if (file.exists()) { - file.delete(); - } - JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); - JavaSource source = new JavaSource(); - JavacTask ct = (JavacTask)comp.getTask(null, null, null, - Arrays.asList(ck.opts), null, Arrays.asList(source)); - try { - if (!ct.call()) { - throw new AssertionError(errorMessage + - source.getCharContent(true)); - } - } catch (Throwable ex) { - throw new AssertionError(errorMessage + - source.getCharContent(true)); - } - check(ck); - } - } - - private void check(CompilationKind ck) throws IOException { - try { - File file = new File("Test$1.class"); - ClassModel classFile = Classfile.of().parse(file.toPath()); - if (ck == CompilationKind.POST_NESTMATES) { - throw new AssertionError("Unexpected constructor tag class!"); - } - boolean inheritsFromObject = - classFile.superclass().orElseThrow().asInternalName().equals("java/lang/Object"); - boolean implementsNoInterface = classFile.interfaces().size() == 0; - boolean noMethods = classFile.methods().size() == 0; - if (!(inheritsFromObject && - implementsNoInterface && - noMethods)) { - throw new AssertionError("The inner classes reused as " + - "access constructor tag for this code must be empty"); - } - } catch (NoSuchFileException ex) { - if (ck == CompilationKind.PRE_NESTMATES) { - throw new AssertionError("Constructor tag class missing!"); - } - } - } - - class JavaSource extends SimpleJavaFileObject { - - String internalSource = - "public class Test {\n" + - " private static class Foo {}\n" + - " public static void main(String[] args){ \n" + - " new Foo();\n" + - " if(false) {\n" + - " new Runnable() {\n" + - " @Override\n" + - " public void run() {\n" + - " System.out.println();\n" + - " }\n" + - " }.run();\n" + - " }\n" + - " }\n" + - "}"; - public JavaSource() { - super(URI.create("Test.java"), JavaFileObject.Kind.SOURCE); - } - - @Override - public CharSequence getCharContent(boolean ignoreEncodingErrors) { - return internalSource; - } - } -} diff --git a/test/langtools/tools/javac/lambda/ClassNotFoundExceptionDueToPrunedCodeTest.java b/test/langtools/tools/javac/lambda/ClassNotFoundExceptionDueToPrunedCodeTest.java new file mode 100644 index 00000000000..d9481a227e4 --- /dev/null +++ b/test/langtools/tools/javac/lambda/ClassNotFoundExceptionDueToPrunedCodeTest.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2023, 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 8314621 + * @summary ClassNotFoundException due to lambda reference to elided anonymous inner class + */ + +public class ClassNotFoundExceptionDueToPrunedCodeTest { + public static void main(String... args) { + var o1 = false ? new Object() {} : null; + Runnable r = () -> { + System.out.println(o1 == o1); + }; + r.run(); + + var o2 = true ? null : new Object() {}; + r = () -> { + System.out.println(o2 == o2); + }; + r.run(); + + var o3 = switch (0) { default -> { if (false) yield new Object() { }; else yield null; } }; + r = () -> System.out.println(o3); + r.run(); + + var o4 = switch (0) { default -> { if (true) yield null; else yield new Object() { }; } }; + r = () -> System.out.println(o4); + r.run(); + } +}