Skip to content
This repository has been archived by the owner on Sep 2, 2022. It is now read-only.

Commit

Permalink
8269802: javac fails to compile nested pattern matching switches
Browse files Browse the repository at this point in the history
8269808: javac generates class with invalid stack map

Reviewed-by: mcimadamore
  • Loading branch information
lahodaj committed Jul 7, 2021
1 parent 2daf39a commit 815e4af
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 1 deletion.
Expand Up @@ -386,6 +386,7 @@ private void handleSwitch(JCTree tree,
hasNullCase = true;
}
}
selector = translate(selector);
statements.append(make.at(tree.pos).VarDef(temp, !hasNullCase ? attr.makeNullCheck(selector)
: selector));
VarSymbol index = new VarSymbol(Flags.SYNTHETIC,
Expand Down Expand Up @@ -469,6 +470,8 @@ private void handleSwitch(JCTree tree,
currentValue = prevCurrentValue;
bindingContext.pop();
}
} else {
c.stats = translate(c.stats);
}
if (enumSwitch) {
var labels = c.labels;
Expand Down
122 changes: 121 additions & 1 deletion test/langtools/tools/javac/patterns/Switches.java
Expand Up @@ -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
Expand Down Expand Up @@ -66,6 +67,11 @@ void run() {
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) {
Expand Down Expand Up @@ -119,6 +125,13 @@ void npeTest(Consumer<I> testCase) {
}
}

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());
Expand Down Expand Up @@ -366,6 +379,113 @@ void exhaustiveStatementSane(Object o) {
}
}

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
Expand Down

1 comment on commit 815e4af

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.