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]

Java: Fix PRs 234, 238, and 255


The following patches fix these Java PRs:

gcj/234: methods inheirited from base class are not resolved to
interface
 http://sourceware.cygnus.com/cgi-bin/gnatsweb.pl?cmd=view&pr=234&database=java

gcj/238: Can't call methods from Object on an inner class
 http://sourceware.cygnus.com/cgi-bin/gnatsweb.pl?cmd=view&pr=238&database=java

gcj/255: Fields can be static in an inner class when they are final
 http://sourceware.cygnus.com/cgi-bin/gnatsweb.pl?cmd=view&pr=255&database=java

The PR 238 fix is an improved version of a patch posted previously by
Tom Tromey. Rather than using an additional loop to remove duplicate
methods, this one uses a hashtable to ensure the same class is not
searched more than once.

  [ bryce ]


2000-06-09  Bryce McKinlay  <bryce@albatross.co.nz>

	* parse.y (find_most_specific_methods_list): If several methods
	are equally specific but only one of them is non-abstract, return
	the non-abstract one. Fix for PR gcj/234.

Index: parse.y
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/parse.y,v
retrieving revision 1.177
diff -u -r1.177 parse.y
--- parse.y	2000/06/06 18:46:16	1.177
+++ parse.y	2000/06/09 05:13:24
@@ -10212,13 +10212,36 @@
     if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
       new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
 
+  /* If there are several and only one of them is non-abstract, pick it. */
+  if (new_list && TREE_CHAIN (new_list))
+    {
+      tree non_abstract = NULL_TREE;
+      tree c;
+      for (c = new_list; c; c = TREE_CHAIN (c))
+        {
+	  if (! METHOD_ABSTRACT (TREE_VALUE (c)))
+	    {
+	      if (non_abstract == NULL)
+	        non_abstract = c;
+	      else
+	        /* More than one non-abstract method */
+	        return new_list;
+	    }
+	}
+      if (non_abstract != NULL)
+        {
+	  new_list = non_abstract;	  
+          TREE_CHAIN (new_list) = NULL_TREE;
+	}
+    }
+
   /* If we have several and they're all abstract, just pick the
      closest one. */
 
   if (new_list && TREE_CHAIN (new_list))
     {
       tree c;
-      for (c = new_list; c && METHOD_ABSTRACT (TREE_VALUE (c)); 
+      for (c = new_list; c && METHOD_ABSTRACT (TREE_VALUE (c));
 	   c = TREE_CHAIN (c))
         ;
       if (!c)
2000-06-09  Bryce McKinlay  <bryce@albatross.co.nz>

	* parse.y (find_applicable_accessible_methods_list): Use a hashtable
	to track searched classes, and do not search the same class more than
	once. Call find_applicable_accessible_methods_list on immediate
	superclass, instead of search_applicable_method_list on all ancestors.
	Fix for PR gcj/238.

Index: parse.y
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/parse.y,v
retrieving revision 1.177
diff -u -r1.177 parse.y
--- parse.y	2000/06/06 18:46:16	1.177
+++ parse.y	2000/06/09 05:32:33
@@ -10024,9 +10024,29 @@
      int lc;
      tree class, name, arglist;
 {
-  static int object_done = 0;
+  static struct hash_table t, *searched_classes = NULL;
+  static int search_not_done = 0;
   tree list = NULL_TREE, all_list = NULL_TREE;
 
+  /* Check the hash table to determine if this class has been searched 
+     already. */
+  if (searched_classes)
+    {
+      if (hash_lookup (searched_classes, 
+		       (const hash_table_key) class, FALSE, NULL))
+	return NULL;
+    }
+  else
+    {
+      hash_table_init (&t, hash_newfunc, java_hash_hash_tree_node,
+		       java_hash_compare_tree_node);
+      searched_classes = &t;
+    }
+    
+  search_not_done++;
+  hash_lookup (searched_classes, 
+	       (const hash_table_key) class, TRUE, NULL);
+
   if (!CLASS_LOADED_P (class) && !CLASS_FROM_SOURCE_P (class))
     {
       load_class (class, 1);
@@ -10036,30 +10056,8 @@
   /* Search interfaces */
   if (CLASS_INTERFACE (TYPE_NAME (class)))
     {
-      static struct hash_table t, *searched_interfaces = NULL;
-      static int search_not_done = 0;
       int i, n;
       tree basetype_vec = TYPE_BINFO_BASETYPES (class);
-
-      /* Search in the hash table, otherwise create a new one if
-         necessary and insert the new entry. */
-
-      if (searched_interfaces)
-	{
-	  if (hash_lookup (searched_interfaces, 
-			   (const hash_table_key) class, FALSE, NULL))
-	    return NULL;
-	}
-      else
-	{
-	  hash_table_init (&t, hash_newfunc, java_hash_hash_tree_node,
-			   java_hash_compare_tree_node);
-	  searched_interfaces = &t;
-	}
-
-      hash_lookup (searched_interfaces, 
-		   (const hash_table_key) class, TRUE, NULL);
-
       search_applicable_methods_list (lc, TYPE_METHODS (class), 
 				      name, arglist, &list, &all_list);
       n = TREE_VEC_LENGTH (basetype_vec);
@@ -10068,23 +10066,9 @@
 	  tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
 	  tree rlist;
 
-	  search_not_done++;
 	  rlist = find_applicable_accessible_methods_list (lc,  t, name, 
 							   arglist);
 	  list = chainon (rlist, list);
-	  search_not_done--;
-	}
-
-      /* We're done. Reset the searched interfaces list and finally search
-         java.lang.Object */
-      if (!search_not_done)
-	{  
-	  if (!object_done)
-	    search_applicable_methods_list (lc, 
-					    TYPE_METHODS (object_type_node),
-					    name, arglist, &list, &all_list);
-	  hash_table_free (searched_interfaces);
-	  searched_interfaces = NULL;  
 	}
     }
   /* Search classes */
@@ -10100,7 +10084,6 @@
       {
 	tree basetype_vec = TYPE_BINFO_BASETYPES (sc);
 	int n = TREE_VEC_LENGTH (basetype_vec), i;
-	object_done = 1;
 	for (i = 1; i < n; i++)
 	  {
 	    tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
@@ -10112,7 +10095,6 @@
 		list = chainon (rlist, list);
 	      }
 	  }
-	object_done = 0;
       }
 
       /* Search enclosing context of inner classes before looking
@@ -10132,11 +10114,36 @@
 	class = CLASSTYPE_SUPER (sc);
       else
 	class = sc;
+	
+      /* Search superclass */
+      if (!lc && CLASSTYPE_SUPER (class) != NULL_TREE)
+        {
+	  tree rlist;
+	  class = CLASSTYPE_SUPER (class);
+	  rlist = find_applicable_accessible_methods_list (lc, class, 
+							   name, arglist);
+	  list = chainon (rlist, list);
+	}
+    }
+
+  search_not_done--;
 
-      for (class = (lc ? NULL_TREE : CLASSTYPE_SUPER (class)); 
-        class; class = CLASSTYPE_SUPER (class))
-       search_applicable_methods_list (lc, TYPE_METHODS (class), 
-                                       name, arglist, &list, &all_list);
+  /* We're done. Reset the searched classes list and finally search
+     java.lang.Object if it wasn't searched already. */
+  if (!search_not_done)
+    {
+      if (!lc
+          && TYPE_METHODS (object_type_node)
+          && !hash_lookup (searched_classes, 
+			   (const hash_table_key) object_type_node, 
+			   FALSE, NULL))
+        {
+	  search_applicable_methods_list (lc, 
+					  TYPE_METHODS (object_type_node),
+					  name, arglist, &list, &all_list);
+	}
+      hash_table_free (searched_classes);
+      searched_classes = NULL;
     }
 
   /* Either return the list obtained or all selected (but
@@ -10144,7 +10151,7 @@
   return (!list ? all_list : list);
 }
 
-/* Effectively search for the approriate method in method */
+/* Effectively search for the appropriate method in method */
 
 static void 
 search_applicable_methods_list (lc, method, name, arglist, list, all_list)
@@ -10173,7 +10180,7 @@
 	    *all_list = tree_cons (NULL_TREE, method, *list);
 	}
     }
-}    
+}
 
 /* 15.11.2.2 Choose the Most Specific Method */
 
2000-06-09  Bryce McKinlay  <bryce@albatross.co.nz>

	* parse.y (register_fields): Permit static fields in inner classes
	if they are final. Fix for PR gcj/255.

Index: parse.y
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/parse.y,v
retrieving revision 1.177
diff -u -r1.177 parse.y
--- parse.y	2000/06/06 18:46:16	1.177
+++ parse.y	2000/06/09 05:03:33
@@ -4102,11 +4102,11 @@
       tree init = TREE_VALUE (current);
       tree current_name = EXPR_WFL_NODE (cl);
 
-      /* Can't declare static fields in inner classes */
+      /* Can't declare non-final static fields in inner classes */
       if ((flags & ACC_STATIC) && !TOPLEVEL_CLASS_TYPE_P (class_type)
-	  && !CLASS_INTERFACE (TYPE_NAME (class_type)))
+	  && !(flags & ACC_FINAL)
 	parse_error_context 
-	  (cl, "Field `%s' can't be static in innerclass `%s'. Only members of interfaces and top-level classes can be static",
+	  (cl, "Field `%s' can't be static in inner class `%s' unless it is final",
 	   IDENTIFIER_POINTER (EXPR_WFL_NODE (cl)),
 	   lang_printable_name (class_type, 0));
 

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