From 8102f436f5586253302cd8cef49bfe2b4af41693 Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Thu, 13 Nov 2025 15:28:08 +0000 Subject: [PATCH] 8371480: VerifyError after JDK-8369654 Reviewed-by: mcimadamore --- .../com/sun/tools/javac/code/Types.java | 2 +- .../classes/com/sun/tools/javac/jvm/Code.java | 19 +-- .../VerifierErrorWrongSuperTypeTest.java | 130 ++++++++++++++++++ 3 files changed, 142 insertions(+), 9 deletions(-) create mode 100644 test/langtools/tools/javac/switchexpr/VerifierErrorWrongSuperTypeTest.java diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java index ffd304c18a2..d59505555f2 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java @@ -3971,7 +3971,7 @@ public class Types { * Return the minimum types of a closure, suitable for computing * compoundMin or glb. */ - private List closureMin(List cl) { + public List closureMin(List cl) { ListBuffer classes = new ListBuffer<>(); ListBuffer interfaces = new ListBuffer<>(); Set toSkip = new HashSet<>(); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java index 7899b8335b6..227143c3148 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java @@ -1854,14 +1854,17 @@ public class Code { } else { t1 = types.skipTypeVars(t1, false); t2 = types.skipTypeVars(t2, false); - List intersection = types.intersect( - t1.hasTag(ARRAY) ? - List.of(syms.serializableType, syms.cloneableType, syms.objectType) : - types.erasedSupertypes(t1), - t2.hasTag(ARRAY) ? - List.of(syms.serializableType, syms.cloneableType, syms.objectType) : - types.erasedSupertypes(t2)); - return intersection.head; + List result = types.closureMin( + types.intersect( + t1.hasTag(ARRAY) ? + List.of(syms.serializableType, syms.cloneableType, syms.objectType) : + types.erasedSupertypes(t1), + t2.hasTag(ARRAY) ? + List.of(syms.serializableType, syms.cloneableType, syms.objectType) : + types.erasedSupertypes(t2) + ) + ); + return result.head; } } diff --git a/test/langtools/tools/javac/switchexpr/VerifierErrorWrongSuperTypeTest.java b/test/langtools/tools/javac/switchexpr/VerifierErrorWrongSuperTypeTest.java new file mode 100644 index 00000000000..115bf8980b0 --- /dev/null +++ b/test/langtools/tools/javac/switchexpr/VerifierErrorWrongSuperTypeTest.java @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2025, 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 + * @summary VerifyError after JDK-8369654, incorrect supertype + * @library /tools/lib + * @modules jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.main + * jdk.compiler/com.sun.tools.javac.util + * jdk.compiler/com.sun.tools.javac.code + * @build toolbox.ToolBox toolbox.JavacTask + * @run main VerifierErrorWrongSuperTypeTest + */ + +import java.util.*; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import toolbox.TestRunner; +import toolbox.ToolBox; +import toolbox.JavaTask; +import toolbox.JavacTask; +import toolbox.Task; +import toolbox.Task.OutputKind; + +public class VerifierErrorWrongSuperTypeTest extends TestRunner { + ToolBox tb; + + VerifierErrorWrongSuperTypeTest() { + super(System.err); + tb = new ToolBox(); + } + + protected void runTests() throws Exception { + runTests(m -> new Object[]{Paths.get(m.getName())}); + } + + Path[] findJavaFiles(Path... paths) throws IOException { + return tb.findJavaFiles(paths); + } + + public static void main(String... args) throws Exception { + VerifierErrorWrongSuperTypeTest t = new VerifierErrorWrongSuperTypeTest(); + t.runTests(); + } + + @Test + public void testCompatibilityAfterMakingSuperclassSealed(Path base) throws Exception { + Path src = base.resolve("src"); + Path pkg = src.resolve("p"); + Path v = pkg.resolve("V"); + tb.writeJavaFiles(v, + """ + package p; + public abstract class V {} + """ + ); + Path d = pkg.resolve("D"); + tb.writeJavaFiles(d, + """ + package p; + public abstract class D extends V implements Cloneable {} + """ + ); + Path a = pkg.resolve("A"); + tb.writeJavaFiles(a, + """ + package p; + public class A extends V implements Cloneable {} + """ + ); + Path t = src.resolve("T"); + tb.writeJavaFiles(t, + """ + import p.A; + import p.D; + import p.V; + class T { + public static void main(String[] args) { + new T().foo(false, null); + } + void foo(boolean b, D d) { + V u = b ? d : new A(); + g(u); + } + void g(V u) {} + } + """ + ); + Path out = base.resolve("out"); + Files.createDirectories(out); + new JavacTask(tb) + .outdir(out) + .files(findJavaFiles(src)) + .run(); + + try { + new JavaTask(tb) + .classpath(out.toString()) + .classArgs("T") + .run(); + } catch (Throwable error) { + throw new AssertionError("execution failed"); + } + } +}