8294670: Enhanced switch statements have an implicit default which does not complete normally
Reviewed-by: vromero
This commit is contained in:
parent
95dd376ba2
commit
7bc9692a51
src/jdk.compiler/share/classes/com/sun/tools/javac/comp
test/langtools/tools/javac
@ -694,7 +694,7 @@ public class Flow {
|
||||
log.error(tree, Errors.NotExhaustiveStatement);
|
||||
}
|
||||
}
|
||||
if (!tree.hasUnconditionalPattern) {
|
||||
if (!tree.hasUnconditionalPattern && !exhaustiveSwitch) {
|
||||
alive = Liveness.ALIVE;
|
||||
}
|
||||
alive = alive.or(resolveBreaks(tree, prevPendingExits));
|
||||
|
@ -84,7 +84,6 @@ public class EnumTypeChanges {
|
||||
case B -> { return "B"; }
|
||||
case EnumTypeChangesEnum x when e == EnumTypeChangesEnum.A -> throw new AssertionError();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
String expressionEnumExhaustive(EnumTypeChangesEnum e) {
|
||||
|
@ -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 Exhaustiveness extends TestRunner {
|
||||
private void test(Object obj) {
|
||||
switch (obj) {
|
||||
case String s: return;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
""",
|
||||
@ -1010,6 +1010,7 @@ public class Exhaustiveness extends TestRunner {
|
||||
""");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonPrimitiveBooleanGuard(Path base) throws Exception {
|
||||
doTest(base,
|
||||
new String[0],
|
||||
@ -1056,6 +1057,119 @@ public class Exhaustiveness extends TestRunner {
|
||||
"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");
|
||||
|
@ -93,7 +93,6 @@ public class SwitchNull {
|
||||
case C: return 2;
|
||||
case null: return -1;
|
||||
}
|
||||
throw new AssertionError(String.valueOf(e));
|
||||
}
|
||||
|
||||
private int switchEnumWithDefault(E e) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user