changeset 640:594b3c2ef585

6978574: return statement in try block with multi-catch causes ClassFormatError Summary: Wrong nested loops in Gen.java causes javac to generate bad bytecode Reviewed-by: jjg
author mcimadamore
date Mon, 23 Aug 2010 17:00:07 +0100
parents 995bcdb9a41d
children 6b95dd682538
files src/share/classes/com/sun/tools/javac/jvm/Gen.java test/tools/javac/multicatch/T6978574.java
diffstat 2 files changed, 68 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Mon Aug 23 16:59:30 2010 +0100
+++ b/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Mon Aug 23 17:00:07 2010 +0100
@@ -1455,24 +1455,27 @@
                       List<Integer> gaps) {
             if (startpc != endpc) {
                 List<JCExpression> subClauses = TreeInfo.isMultiCatch(tree) ?
-                    ((JCTypeDisjoint)tree.param.vartype).components :
-                    List.of(tree.param.vartype);
-                for (JCExpression subCatch : subClauses) {
-                    int catchType = makeRef(tree.pos(), subCatch.type);
-                    List<Integer> lGaps = gaps;
-                    while (lGaps.nonEmpty()) {
-                        int end = lGaps.head.intValue();
+                        ((JCTypeDisjoint)tree.param.vartype).components :
+                        List.of(tree.param.vartype);
+                while (gaps.nonEmpty()) {
+                    for (JCExpression subCatch : subClauses) {
+                        int catchType = makeRef(tree.pos(), subCatch.type);
+                        int end = gaps.head.intValue();
                         registerCatch(tree.pos(),
                                       startpc,  end, code.curPc(),
                                       catchType);
-                        lGaps = lGaps.tail;
-                        startpc = lGaps.head.intValue();
-                        lGaps = lGaps.tail;
                     }
-                    if (startpc < endpc)
+                    gaps = gaps.tail;
+                    startpc = gaps.head.intValue();
+                    gaps = gaps.tail;
+                }
+                if (startpc < endpc) {
+                    for (JCExpression subCatch : subClauses) {
+                        int catchType = makeRef(tree.pos(), subCatch.type);
                         registerCatch(tree.pos(),
                                       startpc, endpc, code.curPc(),
                                       catchType);
+                    }
                 }
                 VarSymbol exparam = tree.param.sym;
                 code.statBegin(tree.pos);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/multicatch/T6978574.java	Mon Aug 23 17:00:07 2010 +0100
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6978574
+ * @summary  return statement in try block with multi-catch causes ClassFormatError
+ */
+
+public class T6978574  {
+    static class A extends Exception { }
+    static class B extends Exception { }
+
+    static void foo() throws A { throw new A(); }
+    static void bar() throws B { throw new B(); }
+
+    static void test(boolean b) {
+        try {
+            if (b) foo(); else bar();
+            return; // This should *not* cause ClassFormatError
+        } catch (final A | B e ) { caught = true; }
+        return;
+    }
+
+    static boolean caught = false;
+
+    public static void main(String[] args) {
+        test(true);
+        if (!caught) throw new AssertionError();
+        caught = false;
+        test(false);
+        if (!caught) throw new AssertionError();
+    }
+}