diff --git a/src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java b/src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java index 8cc67807450..b7c9cb48812 100644 --- a/src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java +++ b/src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java @@ -468,22 +468,23 @@ public class SwitchBootstraps { Label notNumber = cb.newLabel(); cb.aload(SELECTOR_OBJ); cb.instanceof_(ConstantDescs.CD_Number); - if (selectorType == long.class || selectorType == float.class || selectorType == double.class) { + if (selectorType == long.class || selectorType == float.class || selectorType == double.class || + selectorType == Long.class || selectorType == Float.class || selectorType == Double.class) { cb.ifeq(next); } else { cb.ifeq(notNumber); } cb.aload(SELECTOR_OBJ); cb.checkcast(ConstantDescs.CD_Number); - if (selectorType == long.class) { + if (selectorType == long.class || selectorType == Long.class) { cb.invokevirtual(ConstantDescs.CD_Number, "longValue", MethodTypeDesc.of(ConstantDescs.CD_long)); - } else if (selectorType == float.class) { + } else if (selectorType == float.class || selectorType == Float.class) { cb.invokevirtual(ConstantDescs.CD_Number, "floatValue", MethodTypeDesc.of(ConstantDescs.CD_float)); - } else if (selectorType == double.class) { + } else if (selectorType == double.class || selectorType == Double.class) { cb.invokevirtual(ConstantDescs.CD_Number, "doubleValue", MethodTypeDesc.of(ConstantDescs.CD_double)); diff --git a/test/langtools/tools/javac/patterns/PrimitiveInstanceOfComboTest.java b/test/langtools/tools/javac/patterns/PrimitiveInstanceOfComboTest.java index bfc3993124b..113c1214452 100644 --- a/test/langtools/tools/javac/patterns/PrimitiveInstanceOfComboTest.java +++ b/test/langtools/tools/javac/patterns/PrimitiveInstanceOfComboTest.java @@ -43,6 +43,10 @@ import combo.ComboTask; import combo.ComboTestHelper; import toolbox.ToolBox; +import javax.tools.Diagnostic; +import javax.tools.JavaFileObject; +import java.util.List; + public class PrimitiveInstanceOfComboTest extends ComboInstance { private static final String JAVA_VERSION = System.getProperty("java.specification.version"); @@ -82,25 +86,49 @@ public class PrimitiveInstanceOfComboTest extends ComboInstance {} + } + } + } + """; + @Override protected void doWork() throws Throwable { ComboTask task1 = newCompilationTask() .withSourceFromTemplate(test1.replace("#{TYPE1}", type1.code).replace("#{TYPE2}", type2.code)) .withOption("--enable-preview") - .withOption("-source").withOption(JAVA_VERSION);; + .withOption("-source").withOption(JAVA_VERSION); ComboTask task2 = newCompilationTask() .withSourceFromTemplate(test2.replace("#{TYPE1}", type1.code).replace("#{TYPE2}", type2.code)) .withOption("--enable-preview") - .withOption("-source").withOption(JAVA_VERSION);; + .withOption("-source").withOption(JAVA_VERSION); + + ComboTask task3 = newCompilationTask() + .withSourceFromTemplate(test3.replace("#{TYPE1}", type1.code).replace("#{TYPE2}", type2.code)) + .withOption("--enable-preview") + .withOption("-source").withOption(JAVA_VERSION); task1.generate(result1 -> { task2.generate(result2 -> { - if (result1.hasErrors() ^ result2.hasErrors()) { - throw new AssertionError("Unexpected result: " + - "\n task1: " + result1.hasErrors() + ", info: " + result1.compilationInfo() + - "\n task1: " + result2.hasErrors() + ", info: " + result2.compilationInfo()); - } + task3.generate(result3 -> { + List> list1 = result1.diagnosticsForKind(Diagnostic.Kind.ERROR); + List> list2 = result2.diagnosticsForKind(Diagnostic.Kind.ERROR); + List> list3 = result3.diagnosticsForKind(Diagnostic.Kind.ERROR).stream().filter(e -> !e.getCode().equals("compiler.err.not.exhaustive.statement")).toList(); + if (!(list1.size() == list2.size() && list3.size() == list2.size())) { + throw new AssertionError("Unexpected result: " + + "\n task1: " + result1.hasErrors() + ", info: " + result1.compilationInfo() + + "\n task2: " + result2.hasErrors() + ", info: " + result2.compilationInfo() + + "\n task3: " + result3.hasErrors() + ", info: " + result3.compilationInfo() + ); + } + }); }); }); } diff --git a/test/langtools/tools/javac/patterns/PrimitivePatternsSwitch.java b/test/langtools/tools/javac/patterns/PrimitivePatternsSwitch.java index 8f97ae2425e..1d78fe98147 100644 --- a/test/langtools/tools/javac/patterns/PrimitivePatternsSwitch.java +++ b/test/langtools/tools/javac/patterns/PrimitivePatternsSwitch.java @@ -113,6 +113,13 @@ public class PrimitivePatternsSwitch { assertEquals(1, testByteWrapperToIntUnconditionallyExact()); assertEquals(1, testIntegerWrapperToFloat()); assertEquals(-1, testIntegerWrapperToFloatInexact()); + assertEquals(Character.MAX_VALUE, testUnboxingAndWideningCharacter1(Character.MAX_VALUE)); + assertEquals(Character.MAX_VALUE, testUnboxingAndWideningCharacter2(Character.MAX_VALUE)); + assertEquals(Character.MAX_VALUE, testUnboxingAndWideningCharacter3(Character.MAX_VALUE)); + assertEquals(Float.MAX_VALUE, testUnboxingAndWideningFloat(Float.MAX_VALUE)); + assertEquals(Float.MAX_VALUE, testUnboxingAndWideningFloatExplicitCast(Float.MAX_VALUE)); + assertEquals(42f, testUnboxingAndWideningLong(42L)); + assertEquals(2, testUnboxingAndWideningLong(Long.MAX_VALUE)); } public static int primitiveSwitch(int i) { @@ -565,6 +572,43 @@ public class PrimitivePatternsSwitch { }; } + public static char testUnboxingAndWideningCharacter1(Character test) { + return switch (test) { + case char c -> c; + }; + } + + public static int testUnboxingAndWideningCharacter2(Character test) { + return switch (test) { + case int c -> c; + }; + } + + public static float testUnboxingAndWideningCharacter3(Character test) { + return switch (test) { + case float f -> f; + }; + } + public static float testUnboxingAndWideningLong(Long test) { + return switch (test) { + case float y -> y; + default -> 2; + }; + } + + public static double testUnboxingAndWideningFloat(Float test) { + return switch (test) { + case double y -> y; + default -> 2; + }; + } + + public static double testUnboxingAndWideningFloatExplicitCast(Object test) { + return switch ((Float) test) { + case double y -> y; + default -> 2; + }; + } record R_Integer(Integer x) {} record R_int(int x) {} diff --git a/test/langtools/tools/javac/patterns/PrimitivePatternsSwitchErrors.java b/test/langtools/tools/javac/patterns/PrimitivePatternsSwitchErrors.java index e0e153eb0f5..72489d562ea 100644 --- a/test/langtools/tools/javac/patterns/PrimitivePatternsSwitchErrors.java +++ b/test/langtools/tools/javac/patterns/PrimitivePatternsSwitchErrors.java @@ -241,4 +241,24 @@ public class PrimitivePatternsSwitchErrors { case int b -> -2 ; }; } + + public static int disallowedUnboxingAndNarrowing1() { + Long n = 42l; + return switch (n) { // Error - not exhaustive and not allowed + case char c -> -1 ; + }; + } + + public static int disallowedUnboxingAndNarrowing2() { + Long n = 42l; + return switch (n) { // Error - not exhaustive and not allowed + case int c -> -1 ; + }; + } + + public static char disallowedUnboxingAndWidening(Short test) { + return switch (test) { + case char c -> c; // Error - not exhaustive and not allowed + }; + } } diff --git a/test/langtools/tools/javac/patterns/PrimitivePatternsSwitchErrors.out b/test/langtools/tools/javac/patterns/PrimitivePatternsSwitchErrors.out index 97b0d67cec7..22178944b7c 100644 --- a/test/langtools/tools/javac/patterns/PrimitivePatternsSwitchErrors.out +++ b/test/langtools/tools/javac/patterns/PrimitivePatternsSwitchErrors.out @@ -26,6 +26,9 @@ PrimitivePatternsSwitchErrors.java:179:18: compiler.err.prob.found.req: (compile PrimitivePatternsSwitchErrors.java:189:18: compiler.err.unconditional.pattern.and.both.boolean.values PrimitivePatternsSwitchErrors.java:196:18: compiler.err.duplicate.unconditional.pattern PrimitivePatternsSwitchErrors.java:216:18: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.null, int) +PrimitivePatternsSwitchErrors.java:248:18: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.Long, char) +PrimitivePatternsSwitchErrors.java:255:18: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.Long, int) +PrimitivePatternsSwitchErrors.java:261:18: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.Short, char) PrimitivePatternsSwitchErrors.java:30:16: compiler.err.not.exhaustive PrimitivePatternsSwitchErrors.java:37:16: compiler.err.not.exhaustive PrimitivePatternsSwitchErrors.java:44:16: compiler.err.not.exhaustive @@ -35,6 +38,9 @@ PrimitivePatternsSwitchErrors.java:207:9: compiler.err.not.exhaustive.statement PrimitivePatternsSwitchErrors.java:223:16: compiler.err.not.exhaustive PrimitivePatternsSwitchErrors.java:231:16: compiler.err.not.exhaustive PrimitivePatternsSwitchErrors.java:239:16: compiler.err.not.exhaustive +PrimitivePatternsSwitchErrors.java:247:16: compiler.err.not.exhaustive +PrimitivePatternsSwitchErrors.java:254:16: compiler.err.not.exhaustive +PrimitivePatternsSwitchErrors.java:260:16: compiler.err.not.exhaustive - compiler.note.preview.filename: PrimitivePatternsSwitchErrors.java, DEFAULT - compiler.note.preview.recompile -37 errors \ No newline at end of file +43 errors \ No newline at end of file