Java 12: javac crash with switch expression containing try-catch-finally
B. Blaser
bsrbnd at gmail.com
Sat Mar 23 17:24:38 UTC 2019
Hi Jan,
On Thu, 21 Mar 2019 at 18:24, Jan Lahoda <jan.lahoda at oracle.com> wrote:
>
> Hi Bernard,
>
> I was peeking at this, and expected to start to work on this.
>
> I do agree we will need to strip the extra values from the stack, but we
> may also need to set the letExprStackPos at some point.
>
> Jan
Right, this refers to Tagir's second example:
public static void test2() {
System.out.println(switch (0) {
default -> {
try(Stream<?> s = Stream.empty()) {
break 1;
}
}
});
}
The following patch fixes both cases, does this look more reasonable?
Thanks,
Bernard
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java
b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java
@@ -1223,6 +1223,18 @@
return !alive || state.stacksize == letExprStackPos;
}
+ private boolean valueBreak = false;
+
+ public boolean setValueBreak(boolean set) {
+ boolean b = valueBreak;
+ valueBreak = set;
+ return b;
+ }
+
+ public boolean isValueBreak() {
+ return valueBreak;
+ }
+
/**************************************************************************
* Stack map generation
*************************************************************************/
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java
b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java
@@ -1201,10 +1201,12 @@
}
}
int prevLetExprStart =
code.setLetExprStackPos(code.state.stacksize);
+ boolean prevValueBreak = code.setValueBreak(false);
try {
handleSwitch(tree, tree.selector, tree.cases);
} finally {
code.setLetExprStackPos(prevLetExprStart);
+ code.setValueBreak(prevValueBreak);
}
} finally {
stackBeforeSwitchExpression = prevStackBeforeSwitchExpression;
@@ -1707,9 +1709,14 @@
Assert.check(code.isStatementStart());
final Env<GenContext> targetEnv;
if (tree.isValueBreak()) {
- //restore stack as it was before the switch expression:
- for (LocalItem li : stackBeforeSwitchExpression) {
- li.load();
+ if (code.isValueBreak()) {
+ code.emitop0(pop);
+ }
+ else {
+ //restore stack as it was before the switch expression:
+ for (LocalItem li : stackBeforeSwitchExpression) {
+ li.load();
+ }
}
if (inCondSwitchExpression) {
CondItem value = genCond(tree.value, CRT_FLOW_TARGET);
@@ -1732,7 +1739,17 @@
} else {
genExpr(tree.value, pt).load();
code.state.forceStackTop(tree.target.type);
- targetEnv = unwindBreak(tree);
+
+ int prevLetStackPos =
code.setLetExprStackPos(code.state.stacksize);
+ boolean prevValueBreak = code.setValueBreak(true);
+ try {
+ targetEnv = unwindBreak(tree);
+ }
+ finally {
+ code.setLetExprStackPos(prevLetStackPos);
+ code.setValueBreak(prevValueBreak);
+ }
+
targetEnv.info.addExit(code.branch(goto_));
}
} else {
More information about the compiler-dev
mailing list