Pos05.java revision 553:9d9f26857129
1/*
2 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @bug 6943289
27 * @summary  Project Coin: Improved Exception Handling for Java (aka 'multicatch')
28 * @run main Pos05
29 */
30
31import com.sun.tools.classfile.Attribute;
32import com.sun.tools.classfile.ClassFile;
33import com.sun.tools.classfile.Code_attribute;
34import com.sun.tools.classfile.Code_attribute.Exception_data;
35import com.sun.tools.classfile.Method;
36import java.io.*;
37
38public class Pos05 {
39
40    static class Pos05sub {
41
42        class A extends Exception {}
43        class B extends Exception {}
44        class C extends Exception {}
45
46        void test(boolean b1, boolean b2) {
47            try {
48                if (b1) {
49                    throw new A();
50                }
51                else if (b2) {
52                    throw new B();
53                }
54                else {
55                    throw new C();
56                }
57            }
58            catch (final A | B | C ex) {
59                System.out.println("Exception caught");
60            }
61        }
62    }
63
64    static final int TYPES_IN_MULTICATCH = 3;
65    static final String SUBTEST_NAME = Pos05sub.class.getName() + ".class";
66    static final String TEST_METHOD_NAME = "test";
67
68    public static void main(String... args) throws Exception {
69        new Pos05().run();
70    }
71
72    public void run() throws Exception {
73        String workDir = System.getProperty("test.classes");
74        File compiledTest = new File(workDir, SUBTEST_NAME);
75        verifyMulticatchExceptionRanges(compiledTest);
76    }
77
78    void verifyMulticatchExceptionRanges(File f) {
79        System.err.println("verify: " + f);
80        try {
81            int count = 0;
82            ClassFile cf = ClassFile.read(f);
83            Method testMethod = null;
84            for (Method m : cf.methods) {
85                if (m.getName(cf.constant_pool).equals(TEST_METHOD_NAME)) {
86                    testMethod = m;
87                    break;
88                }
89            }
90            if (testMethod == null) {
91                throw new Error("Test method not found");
92            }
93            Code_attribute ea = (Code_attribute)testMethod.attributes.get(Attribute.Code);
94            if (testMethod == null) {
95                throw new Error("Code attribute for test() method not found");
96            }
97            Exception_data firstExceptionTable = null;
98            for (int i = 0 ; i < ea.exception_table_langth; i++) {
99                if (firstExceptionTable == null) {
100                    firstExceptionTable = ea.exception_table[i];
101                }
102                if (ea.exception_table[i].handler_pc != firstExceptionTable.handler_pc ||
103                        ea.exception_table[i].start_pc != firstExceptionTable.start_pc ||
104                        ea.exception_table[i].end_pc != firstExceptionTable.end_pc) {
105                    throw new Error("Multiple overlapping catch clause found in generated code");
106                }
107                count++;
108            }
109            if (count != TYPES_IN_MULTICATCH) {
110                throw new Error("Wrong number of exception data found: " + count);
111            }
112        } catch (Exception e) {
113            e.printStackTrace();
114            throw new Error("error reading " + f +": " + e);
115        }
116    }
117}
118