8294670: Enhanced switch statements have an implicit default which does not complete normally

Reviewed-by: vromero
This commit is contained in:
Jan Lahoda 2022-10-20 15:21:26 +00:00
parent 95dd376ba2
commit 7bc9692a51
4 changed files with 117 additions and 5 deletions

View File

@ -694,7 +694,7 @@ public class Flow {
log.error(tree, Errors.NotExhaustiveStatement); log.error(tree, Errors.NotExhaustiveStatement);
} }
} }
if (!tree.hasUnconditionalPattern) { if (!tree.hasUnconditionalPattern && !exhaustiveSwitch) {
alive = Liveness.ALIVE; alive = Liveness.ALIVE;
} }
alive = alive.or(resolveBreaks(tree, prevPendingExits)); alive = alive.or(resolveBreaks(tree, prevPendingExits));

View File

@ -84,7 +84,6 @@ public class EnumTypeChanges {
case B -> { return "B"; } case B -> { return "B"; }
case EnumTypeChangesEnum x when e == EnumTypeChangesEnum.A -> throw new AssertionError(); case EnumTypeChangesEnum x when e == EnumTypeChangesEnum.A -> throw new AssertionError();
} }
return "";
} }
String expressionEnumExhaustive(EnumTypeChangesEnum e) { String expressionEnumExhaustive(EnumTypeChangesEnum e) {

View File

@ -23,7 +23,7 @@
/** /**
* @test * @test
* @bug 8262891 8268871 8274363 8281100 * @bug 8262891 8268871 8274363 8281100 8294670
* @summary Check exhaustiveness of switches over sealed types. * @summary Check exhaustiveness of switches over sealed types.
* @library /tools/lib * @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api * @modules jdk.compiler/com.sun.tools.javac.api
@ -402,7 +402,7 @@ public class Exhaustiveness extends TestRunner {
private void test(Object obj) { private void test(Object obj) {
switch (obj) { switch (obj) {
case String s: return; case String s: return;
}; }
} }
} }
""", """,
@ -1010,6 +1010,7 @@ public class Exhaustiveness extends TestRunner {
"""); """);
} }
@Test
public void testNonPrimitiveBooleanGuard(Path base) throws Exception { public void testNonPrimitiveBooleanGuard(Path base) throws Exception {
doTest(base, doTest(base,
new String[0], new String[0],
@ -1056,6 +1057,119 @@ public class Exhaustiveness extends TestRunner {
"2 errors"); "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 { private void doTest(Path base, String[] libraryCode, String testCode, String... expectedErrors) throws IOException {
Path current = base.resolve("."); Path current = base.resolve(".");
Path libClasses = current.resolve("libClasses"); Path libClasses = current.resolve("libClasses");

View File

@ -93,7 +93,6 @@ public class SwitchNull {
case C: return 2; case C: return 2;
case null: return -1; case null: return -1;
} }
throw new AssertionError(String.valueOf(e));
} }
private int switchEnumWithDefault(E e) { private int switchEnumWithDefault(E e) {