6978574: return statement in try block with multi-catch causes ClassFormatError

Mon, 23 Aug 2010 17:00:07 +0100

author
mcimadamore
date
Mon, 23 Aug 2010 17:00:07 +0100
changeset 641
594b3c2ef585
parent 640
995bcdb9a41d
child 642
6b95dd682538

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 +}

mercurial