diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java index 20abb281211ab..b88ec78271355 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java @@ -694,7 +694,7 @@ public void visitSwitch(JCSwitch tree) { log.error(tree, Errors.NotExhaustiveStatement); } } - if (!tree.hasUnconditionalPattern) { + if (!tree.hasUnconditionalPattern && !exhaustiveSwitch) { alive = Liveness.ALIVE; } alive = alive.or(resolveBreaks(tree, prevPendingExits)); diff --git a/test/langtools/tools/javac/patterns/EnumTypeChanges.java b/test/langtools/tools/javac/patterns/EnumTypeChanges.java index ba25c8c9108a0..2aa16e6eaf9ac 100644 --- a/test/langtools/tools/javac/patterns/EnumTypeChanges.java +++ b/test/langtools/tools/javac/patterns/EnumTypeChanges.java @@ -84,7 +84,6 @@ String statementEnumExhaustive(EnumTypeChangesEnum e) { case B -> { return "B"; } case EnumTypeChangesEnum x when e == EnumTypeChangesEnum.A -> throw new AssertionError(); } - return ""; } String expressionEnumExhaustive(EnumTypeChangesEnum e) { diff --git a/test/langtools/tools/javac/patterns/Exhaustiveness.java b/test/langtools/tools/javac/patterns/Exhaustiveness.java index 9eede65e574f6..39fe1e558ce32 100644 --- a/test/langtools/tools/javac/patterns/Exhaustiveness.java +++ b/test/langtools/tools/javac/patterns/Exhaustiveness.java @@ -23,7 +23,7 @@ /** * @test - * @bug 8262891 8268871 8274363 8281100 + * @bug 8262891 8268871 8274363 8281100 8294670 * @summary Check exhaustiveness of switches over sealed types. * @library /tools/lib * @modules jdk.compiler/com.sun.tools.javac.api @@ -402,7 +402,7 @@ public class Test { private void test(Object obj) { switch (obj) { case String s: return; - }; + } } } """, @@ -1010,6 +1010,7 @@ private void testStatement(R obj) { """); } + @Test public void testNonPrimitiveBooleanGuard(Path base) throws Exception { doTest(base, new String[0], @@ -1056,6 +1057,119 @@ void test(A arg) { "2 errors"); } + @Test //JDK-8294670 + public void testImplicitDefaultCannotCompleteNormally(Path base) throws Exception { + doTest(base, + new String[0], + """ + package test; + public class Test { + sealed interface A {} + final class B implements A {} + + int test(A arg) { + switch (arg) { + case B b: return 1; + } + } + } + """); + doTest(base, + new String[0], + """ + package test; + public class Test { + sealed interface A {} + final class B implements A {} + + int test(A arg) { + switch (arg) { + case B b: return 1; + default: return 1; + } + } + } + """); + doTest(base, + new String[0], + """ + package test; + public class Test { + sealed interface A {} + final class B implements A {} + + int test(A arg) { + switch (arg) { + case B b: break; + } + } + } + """, + "Test.java:10:5: compiler.err.missing.ret.stmt", + "- compiler.note.preview.filename: Test.java, DEFAULT", + "- compiler.note.preview.recompile", + "1 error"); + doTest(base, + new String[0], + """ + package test; + public class Test { + sealed interface A {} + final class B implements A {} + + int test(A arg) { + switch (arg) { + case B b: return 1; + default: break; + } + } + } + """, + "Test.java:11:5: compiler.err.missing.ret.stmt", + "- compiler.note.preview.filename: Test.java, DEFAULT", + "- compiler.note.preview.recompile", + "1 error"); + doTest(base, + new String[0], + """ + package test; + public class Test { + sealed interface A {} + final class B implements A {} + + int test(A arg) { + switch (arg) { + case B b: + } + } + } + """, + "Test.java:10:5: compiler.err.missing.ret.stmt", + "- compiler.note.preview.filename: Test.java, DEFAULT", + "- compiler.note.preview.recompile", + "1 error"); + doTest(base, + new String[0], + """ + package test; + public class Test { + sealed interface A {} + final class B implements A {} + + int test(A arg) { + switch (arg) { + case B b: return 1; + default: + } + } + } + """, + "Test.java:11:5: compiler.err.missing.ret.stmt", + "- compiler.note.preview.filename: Test.java, DEFAULT", + "- compiler.note.preview.recompile", + "1 error"); + } + private void doTest(Path base, String[] libraryCode, String testCode, String... expectedErrors) throws IOException { Path current = base.resolve("."); Path libClasses = current.resolve("libClasses"); diff --git a/test/langtools/tools/javac/switchnull/SwitchNull.java b/test/langtools/tools/javac/switchnull/SwitchNull.java index 8268c1890b48b..a5e81d751feea 100644 --- a/test/langtools/tools/javac/switchnull/SwitchNull.java +++ b/test/langtools/tools/javac/switchnull/SwitchNull.java @@ -93,7 +93,6 @@ private int switchEnum(E e) { case C: return 2; case null: return -1; } - throw new AssertionError(String.valueOf(e)); } private int switchEnumWithDefault(E e) {