re PR java/26390 (Problem dispatching method call when method does not exist in super...
authorTom Tromey <tromey@redhat.com>
Wed, 15 Mar 2006 18:29:44 +0000 (18:29 +0000)
committerTom Tromey <tromey@gcc.gnu.org>
Wed, 15 Mar 2006 18:29:44 +0000 (18:29 +0000)
gcc/java
PR java/26390:
* class.c (get_interface_method_index): Don't put <clinit> into
interface table.
libjava
PR java/26390:
* link.cc (get_interfaces): Skip <clinit>.
(append_partial_itable): Likewise.

From-SVN: r112093

gcc/java/ChangeLog
gcc/java/class.c
libjava/ChangeLog
libjava/link.cc

index 485e362..9d9091e 100644 (file)
@@ -1,5 +1,11 @@
 2006-03-15  Tom Tromey  <tromey@redhat.com>
 
+       PR java/26390:
+       * class.c (get_interface_method_index): Don't put <clinit> into
+       interface table.
+
+2006-03-15  Tom Tromey  <tromey@redhat.com>
+
        * parse.y (analyze_clinit_body): Ignore empty statements.
 
 2006-03-08  David Daney  <ddaney@avtrex.com>
index 743b9eb..6d666e3 100644 (file)
@@ -1,5 +1,5 @@
 /* Functions related to building classes and their related objects.
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -2303,18 +2303,21 @@ layout_class_methods (tree this_class)
   TYPE_NVIRTUALS (this_class) = dtable_count;
 }
 
-/* Return the index of METHOD in INTERFACE.  This index begins at 1 and is used as an
-   argument for _Jv_LookupInterfaceMethodIdx(). */
+/* Return the index of METHOD in INTERFACE.  This index begins at 1
+   and is used as an argument for _Jv_LookupInterfaceMethodIdx(). */
 int
 get_interface_method_index (tree method, tree interface)
 {
   tree meth;
   int i = 1;
 
-  for (meth = TYPE_METHODS (interface); ; meth = TREE_CHAIN (meth), i++)
+  for (meth = TYPE_METHODS (interface); ; meth = TREE_CHAIN (meth))
     {
       if (meth == method)
        return i;
+      /* We don't want to put <clinit> into the interface table.  */
+      if (! ID_CLINIT_P (DECL_NAME (meth)))
+       ++i;
       gcc_assert (meth != NULL_TREE);
     }
 }
index d08bf16..ff256f6 100644 (file)
@@ -1,3 +1,9 @@
+2006-03-15  Tom Tromey  <tromey@redhat.com>
+
+       PR java/26390:
+       * link.cc (get_interfaces): Skip <clinit>.
+       (append_partial_itable): Likewise.
+
 2006-03-10  Tom Tromey  <tromey@redhat.com>
 
        PR libgcj/25713:
index df148a3..827d318 100644 (file)
@@ -699,9 +699,18 @@ _Jv_Linker::get_interfaces (jclass klass, _Jv_ifaces *ifaces)
          result += get_interfaces (klass->interfaces[i], ifaces);
        }
     }
-    
+
   if (klass->isInterface())
-    result += klass->method_count + 1;
+    {
+      // We want to add 1 plus the number of interface methods here.
+      // But, we take special care to skip <clinit>.
+      ++result;
+      for (int i = 0; i < klass->method_count; ++i)
+       {
+         if (klass->methods[i].name->first() != '<')
+           ++result;
+       }
+    }
   else if (klass->superclass)
     result += get_interfaces (klass->superclass, ifaces);
   return result;
@@ -817,7 +826,7 @@ _Jv_ThrowAbstractMethodError ()
 // Returns the offset at which the next partial ITable should be appended.
 jshort
 _Jv_Linker::append_partial_itable (jclass klass, jclass iface,
-                                    void **itable, jshort pos)
+                                  void **itable, jshort pos)
 {
   using namespace java::lang::reflect;
 
@@ -826,6 +835,10 @@ _Jv_Linker::append_partial_itable (jclass klass, jclass iface,
   
   for (int j=0; j < iface->method_count; j++)
     {
+      // Skip '<clinit>' here.
+      if (iface->methods[j].name->first() == '<')
+       continue;
+
       meth = NULL;
       for (jclass cl = klass; cl; cl = cl->getSuperclass())
         {
@@ -836,12 +849,7 @@ _Jv_Linker::append_partial_itable (jclass klass, jclass iface,
            break;
        }
 
-      if (meth && (meth->name->first() == '<'))
-       {
-         // leave a placeholder in the itable for hidden init methods.
-          itable[pos] = NULL;  
-       }
-      else if (meth)
+      if (meth)
         {
          if ((meth->accflags & Modifier::STATIC) != 0)
            throw new java::lang::IncompatibleClassChangeError