Pos05.java revision 2942:08092deced3f
1/*
2 * Copyright (c) 2010, 2015, 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 * @modules jdk.jdeps/com.sun.tools.classfile
29 * @run main Pos05
30 */
31
32import com.sun.tools.classfile.Attribute;
33import com.sun.tools.classfile.ClassFile;
34import com.sun.tools.classfile.Code_attribute;
35import com.sun.tools.classfile.Code_attribute.Exception_data;
36import com.sun.tools.classfile.Method;
37import java.io.*;
38
39public class Pos05 {
40
41    static class Pos05sub {
42
43        class A extends Exception {}
44        class B extends Exception {}
45        class C extends Exception {}
46
47        void test(boolean b1, boolean b2) {
48            try {
49                if (b1) {
50                    throw new A();
51                }
52                else if (b2) {
53                    throw new B();
54                }
55                else {
56                    throw new C();
57                }
58            }
59            catch (final A | B | C ex) {
60                System.out.println("Exception caught");
61            }
62        }
63    }
64
65    static final int TYPES_IN_MULTICATCH = 3;
66    static final String SUBTEST_NAME = Pos05sub.class.getName() + ".class";
67    static final String TEST_METHOD_NAME = "test";
68
69    public static void main(String... args) throws Exception {
70        new Pos05().run();
71    }
72
73    public void run() throws Exception {
74        String workDir = System.getProperty("test.classes");
75        File compiledTest = new File(workDir, SUBTEST_NAME);
76        verifyMulticatchExceptionRanges(compiledTest);
77    }
78
79    void verifyMulticatchExceptionRanges(File f) {
80        System.err.println("verify: " + f);
81        try {
82            int count = 0;
83            ClassFile cf = ClassFile.read(f);
84            Method testMethod = null;
85            for (Method m : cf.methods) {
86                if (m.getName(cf.constant_pool).equals(TEST_METHOD_NAME)) {
87                    testMethod = m;
88                    break;
89                }
90            }
91            if (testMethod == null) {
92                throw new Error("Test method not found");
93            }
94            Code_attribute ea = (Code_attribute)testMethod.attributes.get(Attribute.Code);
95            if (testMethod == null) {
96                throw new Error("Code attribute for test() method not found");
97            }
98            Exception_data firstExceptionTable = null;
99            for (int i = 0 ; i < ea.exception_table_length; i++) {
100                if (firstExceptionTable == null) {
101                    firstExceptionTable = ea.exception_table[i];
102                }
103                if (ea.exception_table[i].handler_pc != firstExceptionTable.handler_pc ||
104                        ea.exception_table[i].start_pc != firstExceptionTable.start_pc ||
105                        ea.exception_table[i].end_pc != firstExceptionTable.end_pc) {
106                    throw new Error("Multiple overlapping catch clause found in generated code");
107                }
108                count++;
109            }
110            if (count != TYPES_IN_MULTICATCH) {
111                throw new Error("Wrong number of exception data found: " + count);
112            }
113        } catch (Exception e) {
114            e.printStackTrace();
115            throw new Error("error reading " + f +": " + e);
116        }
117    }
118}
119