Java 12: javac crash with switch expression containing try-catch-finally

B. Blaser bsrbnd at gmail.com
Thu Mar 21 15:37:04 UTC 2019


Hi,

On Wed, 20 Mar 2019 at 05:11, Tagir Valeev <amaembo at gmail.com> wrote:
>
> Hello!
>
> I just wanted to draw your attention to the issue JDK-8220018. I
> reported it several weeks ago, but saw no reaction. Probably I failed
> to fill all the necessary fields. The problem is still actual in java
> 12 GA:
>
> // SwTest.java
> public class SwTest {
>     public static void main(String[] args) {
>         System.out.println(switch (0) {
>            default -> {
>                try {
>                    break 1;
>                }
>                catch (Exception ex) {
>                    break 2;
>                }
>                finally {
>                    break 3;
>                }
>            }
>         });
>     }
> }

Is somebody already looking at this?

This is an interesting issue because when generating the final 'break
3', an operand stack size mismatch occurs due to the other already
emitted breaks.
I tried the following tweak to pop the unnecessary operands before
generating the last break, does this look reasonable (langtools:tier1
being OK)?

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,15 @@
         return !alive || state.stacksize == letExprStackPos;
     }

+    public void makeStatementStart() {
+        if (state.stacksize > letExprStackPos) {
+            int toPop = state.stacksize - letExprStackPos;
+            for (int i=0; i<toPop; i++) {
+                emitop0(pop);
+            }
+        }
+    }
+
 /**************************************************************************
  * 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
@@ -1704,7 +1704,7 @@
     }

     public void visitBreak(JCBreak tree) {
-        Assert.check(code.isStatementStart());
+        code.makeStatementStart();
         final Env<GenContext> targetEnv;
         if (tree.isValueBreak()) {
             //restore stack as it was before the switch expression:


More information about the compiler-dev mailing list