test/tools/javac/T7093325.java

changeset 1109
3cdfa97e1be9
child 1482
954541f13717
equal deleted inserted replaced
1108:b5d0b8effc85 1109:3cdfa97e1be9
1 /*
2 * Copyright (c) 2011, 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 7093325
27 * @summary Redundant entry in bytecode exception table
28 */
29
30 import com.sun.source.util.JavacTask;
31 import com.sun.tools.classfile.Attribute;
32 import com.sun.tools.classfile.ClassFile;
33 import com.sun.tools.classfile.Code_attribute;
34 import com.sun.tools.classfile.ConstantPool.*;
35 import com.sun.tools.classfile.Method;
36 import com.sun.tools.javac.api.JavacTool;
37
38 import java.io.File;
39 import java.net.URI;
40 import java.util.Arrays;
41 import javax.tools.JavaCompiler;
42 import javax.tools.JavaFileObject;
43 import javax.tools.SimpleJavaFileObject;
44 import javax.tools.StandardJavaFileManager;
45 import javax.tools.ToolProvider;
46
47
48 public class T7093325 {
49
50 /** global decls ***/
51
52 // Create a single file manager and reuse it for each compile to save time.
53 static StandardJavaFileManager fm = JavacTool.create().getStandardFileManager(null, null, null);
54
55 //statistics
56 static int checkCount = 0;
57
58 enum StatementKind {
59 THROW("throw new RuntimeException();", false, false),
60 RETURN_NONEMPTY("System.out.println(); return;", true, false),
61 RETURN_EMPTY("return;", true, true),
62 APPLY("System.out.println();", true, false);
63
64 String stmt;
65 boolean canInline;
66 boolean empty;
67
68 private StatementKind(String stmt, boolean canInline, boolean empty) {
69 this.stmt = stmt;
70 this.canInline = canInline;
71 this.empty = empty;
72 }
73 }
74
75 enum CatchArity {
76 NONE(""),
77 ONE("catch (A a) { #S1 }"),
78 TWO("catch (B b) { #S2 }"),
79 THREE("catch (C c) { #S3 }"),
80 FOUR("catch (D d) { #S4 }");
81
82 String catchStr;
83
84 private CatchArity(String catchStr) {
85 this.catchStr = catchStr;
86 }
87
88 String catchers() {
89 if (this.ordinal() == 0) {
90 return catchStr;
91 } else {
92 return CatchArity.values()[this.ordinal() - 1].catchers() + catchStr;
93 }
94 }
95 }
96
97 public static void main(String... args) throws Exception {
98 for (CatchArity ca : CatchArity.values()) {
99 for (StatementKind stmt0 : StatementKind.values()) {
100 if (ca.ordinal() == 0) {
101 new T7093325(ca, stmt0).compileAndCheck();
102 continue;
103 }
104 for (StatementKind stmt1 : StatementKind.values()) {
105 if (ca.ordinal() == 1) {
106 new T7093325(ca, stmt0, stmt1).compileAndCheck();
107 continue;
108 }
109 for (StatementKind stmt2 : StatementKind.values()) {
110 if (ca.ordinal() == 2) {
111 new T7093325(ca, stmt0, stmt1, stmt2).compileAndCheck();
112 continue;
113 }
114 for (StatementKind stmt3 : StatementKind.values()) {
115 if (ca.ordinal() == 3) {
116 new T7093325(ca, stmt0, stmt1, stmt2, stmt3).compileAndCheck();
117 continue;
118 }
119 for (StatementKind stmt4 : StatementKind.values()) {
120 if (ca.ordinal() == 4) {
121 new T7093325(ca, stmt0, stmt1, stmt2, stmt3, stmt4).compileAndCheck();
122 continue;
123 }
124 for (StatementKind stmt5 : StatementKind.values()) {
125 new T7093325(ca, stmt0, stmt1, stmt2, stmt3, stmt4, stmt5).compileAndCheck();
126 }
127 }
128 }
129 }
130 }
131 }
132 }
133
134 System.out.println("Total checks made: " + checkCount);
135 }
136
137 /** instance decls **/
138
139 CatchArity ca;
140 StatementKind[] stmts;
141
142 public T7093325(CatchArity ca, StatementKind... stmts) {
143 this.ca = ca;
144 this.stmts = stmts;
145 }
146
147 void compileAndCheck() throws Exception {
148 final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
149 JavaSource source = new JavaSource();
150 JavacTask ct = (JavacTask)tool.getTask(null, fm, null,
151 null, null, Arrays.asList(source));
152 ct.call();
153 verifyBytecode(source);
154 }
155
156 void verifyBytecode(JavaSource source) {
157 checkCount++;
158 boolean lastInlined = false;
159 boolean hasCode = false;
160 int gapsCount = 0;
161 for (int i = 0; i < stmts.length ; i++) {
162 lastInlined = stmts[i].canInline;
163 hasCode = hasCode || !stmts[i].empty;
164 if (lastInlined && hasCode) {
165 hasCode = false;
166 gapsCount++;
167 }
168 }
169 if (!lastInlined) {
170 gapsCount++;
171 }
172
173 //System.out.printf("gaps %d \n %s \n", gapsCount, source.toString());
174
175 File compiledTest = new File("Test.class");
176 try {
177 ClassFile cf = ClassFile.read(compiledTest);
178 if (cf == null) {
179 throw new Error("Classfile not found: " + compiledTest.getName());
180 }
181
182 Method test_method = null;
183 for (Method m : cf.methods) {
184 if (m.getName(cf.constant_pool).equals("test")) {
185 test_method = m;
186 break;
187 }
188 }
189
190 if (test_method == null) {
191 throw new Error("Method test() not found in class Test");
192 }
193
194 Code_attribute code = null;
195 for (Attribute a : test_method.attributes) {
196 if (a.getName(cf.constant_pool).equals(Attribute.Code)) {
197 code = (Code_attribute)a;
198 break;
199 }
200 }
201
202 if (code == null) {
203 throw new Error("Code attribute not found in method test()");
204 }
205
206 int actualGapsCount = 0;
207 for (int i = 0; i < code.exception_table_langth ; i++) {
208 int catchType = code.exception_table[i].catch_type;
209 if (catchType == 0) { //any
210 actualGapsCount++;
211 }
212 }
213
214 if (actualGapsCount != gapsCount) {
215 throw new Error("Bad exception table for test()\n" +
216 "expected gaps: " + gapsCount + "\n" +
217 "found gaps: " + actualGapsCount + "\n" +
218 source);
219 }
220 } catch (Exception e) {
221 e.printStackTrace();
222 throw new Error("error reading " + compiledTest +": " + e);
223 }
224
225 }
226
227 class JavaSource extends SimpleJavaFileObject {
228
229 static final String source_template =
230 "class A extends RuntimeException {} \n" +
231 "class B extends RuntimeException {} \n" +
232 "class C extends RuntimeException {} \n" +
233 "class D extends RuntimeException {} \n" +
234 "class E extends RuntimeException {} \n" +
235 "class Test {\n" +
236 " void test() {\n" +
237 " try { #S0 } #C finally { System.out.println(); }\n" +
238 " }\n" +
239 "}";
240
241 String source;
242
243 public JavaSource() {
244 super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
245 source = source_template.replace("#C", ca.catchers());
246 source = source.replace("#S0", stmts[0].stmt);
247 for (int i = 1; i < ca.ordinal() + 1; i++) {
248 source = source.replace("#S" + i, stmts[i].stmt);
249 }
250 }
251
252 @Override
253 public String toString() {
254 return source;
255 }
256
257 @Override
258 public CharSequence getCharContent(boolean ignoreEncodingErrors) {
259 return source;
260 }
261 }
262 }

mercurial