7005371: Multicatch: assertion error while generating LocalVariableTypeTable attribute

Thu, 09 Dec 2010 15:50:57 +0000

author
mcimadamore
date
Thu, 09 Dec 2010 15:50:57 +0000
changeset 781
e3df8d7a9752
parent 780
1d625fbe6c22
child 782
bcf44475aeee

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

src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java file | annotate | diff | comparison | revisions
test/tools/javac/multicatch/7005371/SubTest.java file | annotate | diff | comparison | revisions
test/tools/javac/multicatch/7005371/T7005371.java file | annotate | diff | comparison | revisions
     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 +}

mercurial