Mon, 23 Aug 2010 17:00:07 +0100
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
src/share/classes/com/sun/tools/javac/jvm/Gen.java | file | annotate | diff | comparison | revisions | |
test/tools/javac/multicatch/T6978574.java | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/classes/com/sun/tools/javac/jvm/Gen.java Mon Aug 23 16:59:30 2010 +0100 1.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/Gen.java Mon Aug 23 17:00:07 2010 +0100 1.3 @@ -1455,24 +1455,27 @@ 1.4 List<Integer> gaps) { 1.5 if (startpc != endpc) { 1.6 List<JCExpression> subClauses = TreeInfo.isMultiCatch(tree) ? 1.7 - ((JCTypeDisjoint)tree.param.vartype).components : 1.8 - List.of(tree.param.vartype); 1.9 - for (JCExpression subCatch : subClauses) { 1.10 - int catchType = makeRef(tree.pos(), subCatch.type); 1.11 - List<Integer> lGaps = gaps; 1.12 - while (lGaps.nonEmpty()) { 1.13 - int end = lGaps.head.intValue(); 1.14 + ((JCTypeDisjoint)tree.param.vartype).components : 1.15 + List.of(tree.param.vartype); 1.16 + while (gaps.nonEmpty()) { 1.17 + for (JCExpression subCatch : subClauses) { 1.18 + int catchType = makeRef(tree.pos(), subCatch.type); 1.19 + int end = gaps.head.intValue(); 1.20 registerCatch(tree.pos(), 1.21 startpc, end, code.curPc(), 1.22 catchType); 1.23 - lGaps = lGaps.tail; 1.24 - startpc = lGaps.head.intValue(); 1.25 - lGaps = lGaps.tail; 1.26 } 1.27 - if (startpc < endpc) 1.28 + gaps = gaps.tail; 1.29 + startpc = gaps.head.intValue(); 1.30 + gaps = gaps.tail; 1.31 + } 1.32 + if (startpc < endpc) { 1.33 + for (JCExpression subCatch : subClauses) { 1.34 + int catchType = makeRef(tree.pos(), subCatch.type); 1.35 registerCatch(tree.pos(), 1.36 startpc, endpc, code.curPc(), 1.37 catchType); 1.38 + } 1.39 } 1.40 VarSymbol exparam = tree.param.sym; 1.41 code.statBegin(tree.pos);
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/test/tools/javac/multicatch/T6978574.java Mon Aug 23 17:00:07 2010 +0100 2.3 @@ -0,0 +1,54 @@ 2.4 +/* 2.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.7 + * 2.8 + * This code is free software; you can redistribute it and/or modify it 2.9 + * under the terms of the GNU General Public License version 2 only, as 2.10 + * published by the Free Software Foundation. 2.11 + * 2.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 2.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2.15 + * version 2 for more details (a copy is included in the LICENSE file that 2.16 + * accompanied this code). 2.17 + * 2.18 + * You should have received a copy of the GNU General Public License version 2.19 + * 2 along with this work; if not, write to the Free Software Foundation, 2.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2.21 + * 2.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2.23 + * or visit www.oracle.com if you need additional information or have any 2.24 + * questions. 2.25 + */ 2.26 + 2.27 +/* 2.28 + * @test 2.29 + * @bug 6978574 2.30 + * @summary return statement in try block with multi-catch causes ClassFormatError 2.31 + */ 2.32 + 2.33 +public class T6978574 { 2.34 + static class A extends Exception { } 2.35 + static class B extends Exception { } 2.36 + 2.37 + static void foo() throws A { throw new A(); } 2.38 + static void bar() throws B { throw new B(); } 2.39 + 2.40 + static void test(boolean b) { 2.41 + try { 2.42 + if (b) foo(); else bar(); 2.43 + return; // This should *not* cause ClassFormatError 2.44 + } catch (final A | B e ) { caught = true; } 2.45 + return; 2.46 + } 2.47 + 2.48 + static boolean caught = false; 2.49 + 2.50 + public static void main(String[] args) { 2.51 + test(true); 2.52 + if (!caught) throw new AssertionError(); 2.53 + caught = false; 2.54 + test(false); 2.55 + if (!caught) throw new AssertionError(); 2.56 + } 2.57 +}