# HG changeset patch # User mcimadamore # Date 1282579207 -3600 # Node ID f50c012cd1f081818d0e6dcdd052e5aafd5e74cd # Parent bb5c39054bf37e8f680cf0a570cabb64b2327d70 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 diff -r bb5c39054bf3 -r f50c012cd1f0 langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Mon Aug 23 16:59:30 2010 +0100 +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Mon Aug 23 17:00:07 2010 +0100 @@ -1455,24 +1455,27 @@ List gaps) { if (startpc != endpc) { List 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 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); diff -r bb5c39054bf3 -r f50c012cd1f0 langtools/test/tools/javac/multicatch/T6978574.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/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(); + } +}