8269802: javac fails to compile nested pattern matching switches

8269808: javac generates class with invalid stack map

Reviewed-by: mcimadamore
This commit is contained in:
Jan Lahoda 2021-07-07 06:24:58 +00:00
parent 2daf39a59b
commit 815e4af35d
2 changed files with 124 additions and 1 deletions
src/jdk.compiler/share/classes/com/sun/tools/javac/comp
test/langtools/tools/javac/patterns

@ -386,6 +386,7 @@ public class TransPatterns extends TreeTranslator {
hasNullCase = true;
}
}
selector = translate(selector);
statements.append(make.at(tree.pos).VarDef(temp, !hasNullCase ? attr.makeNullCheck(selector)
: selector));
VarSymbol index = new VarSymbol(Flags.SYNTHETIC,
@ -469,6 +470,8 @@ public class TransPatterns extends TreeTranslator {
currentValue = prevCurrentValue;
bindingContext.pop();
}
} else {
c.stats = translate(c.stats);
}
if (enumSwitch) {
var labels = c.labels;

@ -22,12 +22,13 @@
*/
import java.util.Objects;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
/*
* @test
* @bug 8262891 8268333 8268896
* @bug 8262891 8268333 8268896 8269802 8269808
* @summary Check behavior of pattern switches.
* @compile --enable-preview -source ${jdk.version} Switches.java
* @run main/othervm --enable-preview Switches
@ -66,6 +67,11 @@ public class Switches {
npeTest(this::npeTestExpression);
exhaustiveStatementSane("");
exhaustiveStatementSane(null);
switchNestingTest(this::switchNestingStatementStatement);
switchNestingTest(this::switchNestingStatementExpression);
switchNestingTest(this::switchNestingExpressionStatement);
switchNestingTest(this::switchNestingExpressionExpression);
switchNestingTest(this::switchNestingIfSwitch);
}
void run(Function<Object, Integer> mapper) {
@ -119,6 +125,13 @@ public class Switches {
}
}
void switchNestingTest(BiFunction<Object, Object, String> testCase) {
assertEquals("string, string", testCase.apply("", ""));
assertEquals("string, other", testCase.apply("", 1));
assertEquals("other, string", testCase.apply(1, ""));
assertEquals("other, other", testCase.apply(1, 1));
}
int typeTestPatternSwitchTest(Object o) {
switch (o) {
case String s: return Integer.parseInt(s.toString());
@ -366,6 +379,113 @@ public class Switches {
}
}
String switchNestingStatementStatement(Object o1, Object o2) {
switch (o1) {
case String s1 -> {
switch (o2) {
case String s2 -> {
return "string, string";
}
default -> {
return "string, other";
}
}
}
default -> {
switch (o2) {
case String s2 -> {
return "other, string";
}
default -> {
return "other, other";
}
}
}
}
}
String switchNestingStatementExpression(Object o1, Object o2) {
switch (o1) {
case String s1 -> {
return switch (o2) {
case String s2 -> "string, string";
default -> "string, other";
};
}
default -> {
return switch (o2) {
case String s2 -> "other, string";
default -> "other, other";
};
}
}
}
String switchNestingExpressionStatement(Object o1, Object o2) {
return switch (o1) {
case String s1 -> {
switch (o2) {
case String s2 -> {
yield "string, string";
}
default -> {
yield "string, other";
}
}
}
default -> {
switch (o2) {
case String s2 -> {
yield "other, string";
}
default -> {
yield "other, other";
}
}
}
};
}
String switchNestingExpressionExpression(Object o1, Object o2) {
return switch (o1) {
case String s1 ->
switch (o2) {
case String s2 -> "string, string";
default -> "string, other";
};
default ->
switch (o2) {
case String s2 -> "other, string";
default -> "other, other";
};
};
}
String switchNestingIfSwitch(Object o1, Object o2) {
BiFunction<Object, Object, String> f = (n1, n2) -> {
if (o1 instanceof CharSequence cs) {
return switch (cs) {
case String s1 ->
switch (o2) {
case String s2 -> "string, string";
default -> "string, other";
};
default ->
switch (o2) {
case String s2 -> "other, string";
default -> "other, other";
};
};
} else {
return switch (o2) {
case String s2 -> "other, string";
default -> "other, other";
};
}
};
return f.apply(o1, o2);
}
//verify that for cases like:
//case ConstantClassClash ->
//ConstantClassClash is interpreted as a field, not as a class