This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Java: Fix PRs 234, 238, and 255
- To: gcc-patches at gcc dot gnu dot org
- Subject: Java: Fix PRs 234, 238, and 255
- From: Bryce McKinlay <bryce at albatross dot co dot nz>
- Date: Fri, 09 Jun 2000 17:53:26 +1200
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));