Thu, 09 Dec 2010 15:50:57 +0000
7005371: Multicatch: assertion error while generating LocalVariableTypeTable attribute
Summary: compiler crashes with assertion error if '-g' option is passed and source contains multicatch
Reviewed-by: jjg
1.1 --- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Thu Dec 09 15:50:34 2010 +0000 1.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Thu Dec 09 15:50:57 2010 +0000 1.3 @@ -1168,7 +1168,7 @@ 1.4 VarSymbol sym = var.sym; 1.5 databuf.appendChar(pool.put(sym.name)); 1.6 Type vartype = sym.erasure(types); 1.7 - if (!types.isSameType(sym.type, vartype)) 1.8 + if (needsLocalVariableTypeEntry(sym.type)) 1.9 nGenericVars++; 1.10 databuf.appendChar(pool.put(typeSig(vartype))); 1.11 databuf.appendChar(var.reg); 1.12 @@ -1185,7 +1185,7 @@ 1.13 for (int i=0; i<code.varBufferSize; i++) { 1.14 Code.LocalVar var = code.varBuffer[i]; 1.15 VarSymbol sym = var.sym; 1.16 - if (types.isSameType(sym.type, sym.erasure(types))) 1.17 + if (!needsLocalVariableTypeEntry(sym.type)) 1.18 continue; 1.19 count++; 1.20 // write variable info 1.21 @@ -1209,6 +1209,14 @@ 1.22 } 1.23 endAttrs(acountIdx, acount); 1.24 } 1.25 + //where 1.26 + private boolean needsLocalVariableTypeEntry(Type t) { 1.27 + //a local variable needs a type-entry if its type T is generic 1.28 + //(i.e. |T| != T) and if it's not an intersection type (not supported 1.29 + //in signature attribute grammar) 1.30 + return (!types.isSameType(t, types.erasure(t)) && 1.31 + !t.isCompound()); 1.32 + } 1.33 1.34 void writeStackMap(Code code) { 1.35 int nframes = code.stackMapBufferSize;
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/test/tools/javac/multicatch/7005371/SubTest.java Thu Dec 09 15:50:57 2010 +0000 2.3 @@ -0,0 +1,41 @@ 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 +import java.util.*; 2.28 + 2.29 +class SubTest { 2.30 + 2.31 + interface Foo {} 2.32 + static class X1 extends Exception implements Foo {} 2.33 + static class X2 extends Exception implements Foo {} 2.34 + 2.35 + void test(boolean cond, List<String> ls) { 2.36 + try { 2.37 + if (cond) 2.38 + throw new X1(); 2.39 + else 2.40 + throw new X2(); 2.41 + } 2.42 + catch (X1 | X2 ex) {} 2.43 + } 2.44 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/test/tools/javac/multicatch/7005371/T7005371.java Thu Dec 09 15:50:57 2010 +0000 3.3 @@ -0,0 +1,100 @@ 3.4 +/* 3.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.7 + * 3.8 + * This code is free software; you can redistribute it and/or modify it 3.9 + * under the terms of the GNU General Public License version 2 only, as 3.10 + * published by the Free Software Foundation. 3.11 + * 3.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 3.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 3.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 3.15 + * version 2 for more details (a copy is included in the LICENSE file that 3.16 + * accompanied this code). 3.17 + * 3.18 + * You should have received a copy of the GNU General Public License version 3.19 + * 2 along with this work; if not, write to the Free Software Foundation, 3.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 3.21 + * 3.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 3.23 + * or visit www.oracle.com if you need additional information or have any 3.24 + * questions. 3.25 + */ 3.26 + 3.27 +/* 3.28 + * @test 3.29 + * @bug 7005371 3.30 + * @summary Multicatch: assertion error while generating LocalVariableTypeTable attribute 3.31 + * @compile -g SubTest.java 3.32 + * @run main T7005371 3.33 + */ 3.34 + 3.35 +import com.sun.tools.classfile.Attribute; 3.36 +import com.sun.tools.classfile.ClassFile; 3.37 +import com.sun.tools.classfile.Code_attribute; 3.38 +import com.sun.tools.classfile.LocalVariableTypeTable_attribute; 3.39 +import com.sun.tools.classfile.Method; 3.40 + 3.41 +import java.io.*; 3.42 + 3.43 +public class T7005371 { 3.44 + 3.45 + static final String SUBTEST_NAME = SubTest.class.getName() + ".class"; 3.46 + static final String TEST_METHOD_NAME = "test"; 3.47 + static final int LVT_LENGTH = 1; 3.48 + static final String LVT_SIG_TYPE = "Ljava/util/List<Ljava/lang/String;>;"; 3.49 + 3.50 + 3.51 + public static void main(String... args) throws Exception { 3.52 + new T7005371().run(); 3.53 + } 3.54 + 3.55 + public void run() throws Exception { 3.56 + String workDir = System.getProperty("test.classes"); 3.57 + System.out.println(workDir); 3.58 + File compiledTest = new File(workDir, SUBTEST_NAME); 3.59 + verifyLocalVariableTypeTableAttr(compiledTest); 3.60 + } 3.61 + 3.62 + void verifyLocalVariableTypeTableAttr(File f) { 3.63 + System.err.println("verify: " + f); 3.64 + try { 3.65 + ClassFile cf = ClassFile.read(f); 3.66 + Method testMethod = null; 3.67 + for (Method m : cf.methods) { 3.68 + if (m.getName(cf.constant_pool).equals(TEST_METHOD_NAME)) { 3.69 + testMethod = m; 3.70 + break; 3.71 + } 3.72 + } 3.73 + if (testMethod == null) { 3.74 + throw new Error("Missing method: " + TEST_METHOD_NAME); 3.75 + } 3.76 + Code_attribute code = (Code_attribute)testMethod.attributes.get(Attribute.Code); 3.77 + if (code == null) { 3.78 + throw new Error("Missing Code attribute for method: " + TEST_METHOD_NAME); 3.79 + } 3.80 + LocalVariableTypeTable_attribute lvt_table = 3.81 + (LocalVariableTypeTable_attribute)code.attributes.get(Attribute.LocalVariableTypeTable); 3.82 + if (lvt_table == null) { 3.83 + throw new Error("Missing LocalVariableTypeTable attribute for method: " + TEST_METHOD_NAME); 3.84 + } 3.85 + if (lvt_table.local_variable_table_length != LVT_LENGTH) { 3.86 + throw new Error("LocalVariableTypeTable has wrong size" + 3.87 + "\nfound: " + lvt_table.local_variable_table_length + 3.88 + "\nrequired: " + LVT_LENGTH); 3.89 + } 3.90 + String sig = 3.91 + cf.constant_pool.getUTF8Value(lvt_table.local_variable_table[0].signature_index); 3.92 + 3.93 + if (sig == null || !sig.equals(LVT_SIG_TYPE)) { 3.94 + throw new Error("LocalVariableTypeTable has wrong signature" + 3.95 + "\nfound: " + sig + 3.96 + "\nrequired: " + LVT_SIG_TYPE); 3.97 + } 3.98 + } catch (Exception e) { 3.99 + e.printStackTrace(); 3.100 + throw new Error("error reading " + f +": " + e); 3.101 + } 3.102 + } 3.103 +}