This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

gcj interface dispatch: Handling the "Object case"


There is a rare condition where gcj will accidentally generate a
_Jv_LookupInterfaceMethod call with java.lang.Object as the "iface" parameter
from bytecode generated by compilers implementing the "new" JLS spec, such as
recent versions of Jikes. This isn't an issue with the existing interface
dispatch but can be a potential problem with the new constant-time
impementation.

Godmar Back provided the following test case and suggested the fix, which is
simply to rearrange lookup_java_method in typeck.c so that we search for methods
in superinterfaces first.

Test case (compile to bytecode with Jikes 1.06):

interface b {
        public boolean equals(Object o);
}

    interface c extends b { }


    public class i implements c
    {
            static void f(c _) {
                    if (_.equals(_)) {
                            System.out.println("Success.");
                    }
            }
            public static void main(String av[]) {
                    f(new i());
            }
    }

Fix:

1999-12-13  Bryce McKinlay <bryce@albatross.co.nz>

        * typeck.c (lookup_java_method): Search superinterfaces first
        when looking up an interface method. From Godmar Back
        <gback@cs.utah.edu>

Index: typeck.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/typeck.c,v
retrieving revision 1.20
diff -u -r1.20 typeck.c
--- typeck.c    1999/11/18 03:59:48     1.20
+++ typeck.c    1999/12/14 01:19:53
@@ -749,25 +749,11 @@
   tree method;
   tree currently_searched = searched_class;

-  while (currently_searched != NULL_TREE)
-    {
-      for (method = TYPE_METHODS (currently_searched);
-          method != NULL_TREE;  method = TREE_CHAIN (method))
-       {
-         tree method_sig = build_java_signature (TREE_TYPE (method));
-         if (DECL_NAME (method) == method_name
-             && method_sig == method_signature)
-           return method;
-       }
-      currently_searched = CLASSTYPE_SUPER (currently_searched);
-    }
-
-  /* If this class is an interface class, search its superinterfaces as
-   * well.  A superinterface is not an interface's superclass: a
+  /* If this class is an interface class, first search its superinterfaces.
+   * A superinterface is not an interface's superclass: a
    * super interface is implemented by the interface.
    */

-  currently_searched = searched_class;
   if (CLASS_INTERFACE (TYPE_NAME (currently_searched)))
     {
       int i;
@@ -805,6 +791,22 @@
            }
        }
     }
+
+  currently_searched = searched_class;
+
+  while (currently_searched != NULL_TREE)
+    {
+      for (method = TYPE_METHODS (currently_searched);
+          method != NULL_TREE;  method = TREE_CHAIN (method))
+       {
+         tree method_sig = build_java_signature (TREE_TYPE (method));
+         if (DECL_NAME (method) == method_name
+             && method_sig == method_signature)
+           return method;
+       }
+      currently_searched = CLASSTYPE_SUPER (currently_searched);
+    }
+
   return NULL_TREE;
 }



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]