re GNATS gcj/238 (Can't call methods from Object on an inner class)

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.

(Fix to the Java PR #238:
 http://sourceware.cygnus.com/ml/java-prs/2000-q2/msg00206.html)

From-SVN: r34727
This commit is contained in:
Bryce McKinlay 2000-06-27 05:18:56 +00:00 committed by Alexandre Petit-Bianco
parent 7b245d2461
commit ad69b5b669
3 changed files with 113 additions and 91 deletions

View File

@ -94,6 +94,14 @@
* lang.c (lang_get_alias_set): Mark parameter with ATTRIBUTE_UNUSED. * lang.c (lang_get_alias_set): Mark parameter with ATTRIBUTE_UNUSED.
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.
2000-06-09 Bryce McKinlay <bryce@albatross.co.nz> 2000-06-09 Bryce McKinlay <bryce@albatross.co.nz>
* parse.y (register_fields): Permit static fields in inner classes * parse.y (register_fields): Permit static fields in inner classes

View File

@ -9496,7 +9496,7 @@ check_inner_class_access (decl, enclosing_type, cl)
|| enclosing_context_p (TREE_TYPE (enclosing_type), TREE_TYPE (decl))) || enclosing_context_p (TREE_TYPE (enclosing_type), TREE_TYPE (decl)))
return; return;
parse_error_context (cl, "Can't access nested %s %s. Only plublic classes and interfaces in other packages can be accessed", parse_error_context (cl, "Can't access nested %s %s. Only public classes and interfaces in other packages can be accessed",
(CLASS_INTERFACE (decl) ? "interface" : "class"), (CLASS_INTERFACE (decl) ? "interface" : "class"),
lang_printable_name (decl, 0)); lang_printable_name (decl, 0));
} }
@ -12799,9 +12799,29 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
int lc; int lc;
tree class, name, arglist; 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; 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)) if (!CLASS_LOADED_P (class) && !CLASS_FROM_SOURCE_P (class))
{ {
load_class (class, 1); load_class (class, 1);
@ -12812,30 +12832,8 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
if (TREE_CODE (TYPE_NAME (class)) == TYPE_DECL if (TREE_CODE (TYPE_NAME (class)) == TYPE_DECL
&& CLASS_INTERFACE (TYPE_NAME (class))) && CLASS_INTERFACE (TYPE_NAME (class)))
{ {
static struct hash_table t, *searched_interfaces = NULL;
static int search_not_done = 0;
int i, n; int i, n;
tree basetype_vec = TYPE_BINFO_BASETYPES (class); 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), search_applicable_methods_list (lc, TYPE_METHODS (class),
name, arglist, &list, &all_list); name, arglist, &list, &all_list);
n = TREE_VEC_LENGTH (basetype_vec); n = TREE_VEC_LENGTH (basetype_vec);
@ -12844,23 +12842,9 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i)); tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
tree rlist; tree rlist;
search_not_done++;
rlist = find_applicable_accessible_methods_list (lc, t, name, rlist = find_applicable_accessible_methods_list (lc, t, name,
arglist); arglist);
list = chainon (rlist, list); 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 */ /* Search classes */
@ -12876,7 +12860,6 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
{ {
tree basetype_vec = TYPE_BINFO_BASETYPES (sc); tree basetype_vec = TYPE_BINFO_BASETYPES (sc);
int n = TREE_VEC_LENGTH (basetype_vec), i; int n = TREE_VEC_LENGTH (basetype_vec), i;
object_done = 1;
for (i = 1; i < n; i++) for (i = 1; i < n; i++)
{ {
tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i)); tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
@ -12888,7 +12871,6 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
list = chainon (rlist, list); list = chainon (rlist, list);
} }
} }
object_done = 0;
} }
/* Search enclosing context of inner classes before looking /* Search enclosing context of inner classes before looking
@ -12909,10 +12891,35 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
else else
class = sc; class = sc;
for (class = (lc ? NULL_TREE : CLASSTYPE_SUPER (class)); /* Search superclass */
class; class = CLASSTYPE_SUPER (class)) if (!lc && CLASSTYPE_SUPER (class) != NULL_TREE)
search_applicable_methods_list (lc, TYPE_METHODS (class), {
name, arglist, &list, &all_list); tree rlist;
class = CLASSTYPE_SUPER (class);
rlist = find_applicable_accessible_methods_list (lc, class,
name, arglist);
list = chainon (rlist, list);
}
}
search_not_done--;
/* 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 /* Either return the list obtained or all selected (but
@ -12920,7 +12927,7 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
return (!list ? all_list : list); return (!list ? all_list : list);
} }
/* Effectively search for the approriate method in method */ /* Effectively search for the appropriate method in method */
static void static void
search_applicable_methods_list (lc, method, name, arglist, list, all_list) search_applicable_methods_list (lc, method, name, arglist, list, all_list)
@ -12949,7 +12956,7 @@ search_applicable_methods_list (lc, method, name, arglist, list, all_list)
*all_list = tree_cons (NULL_TREE, method, *list); *all_list = tree_cons (NULL_TREE, method, *list);
} }
} }
} }
/* 15.11.2.2 Choose the Most Specific Method */ /* 15.11.2.2 Choose the Most Specific Method */

View File

@ -10101,9 +10101,29 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
int lc; int lc;
tree class, name, arglist; 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; 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)) if (!CLASS_LOADED_P (class) && !CLASS_FROM_SOURCE_P (class))
{ {
load_class (class, 1); load_class (class, 1);
@ -10114,30 +10134,8 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
if (TREE_CODE (TYPE_NAME (class)) == TYPE_DECL if (TREE_CODE (TYPE_NAME (class)) == TYPE_DECL
&& CLASS_INTERFACE (TYPE_NAME (class))) && CLASS_INTERFACE (TYPE_NAME (class)))
{ {
static struct hash_table t, *searched_interfaces = NULL;
static int search_not_done = 0;
int i, n; int i, n;
tree basetype_vec = TYPE_BINFO_BASETYPES (class); 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), search_applicable_methods_list (lc, TYPE_METHODS (class),
name, arglist, &list, &all_list); name, arglist, &list, &all_list);
n = TREE_VEC_LENGTH (basetype_vec); n = TREE_VEC_LENGTH (basetype_vec);
@ -10146,23 +10144,9 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i)); tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
tree rlist; tree rlist;
search_not_done++;
rlist = find_applicable_accessible_methods_list (lc, t, name, rlist = find_applicable_accessible_methods_list (lc, t, name,
arglist); arglist);
list = chainon (rlist, list); 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 */ /* Search classes */
@ -10178,7 +10162,6 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
{ {
tree basetype_vec = TYPE_BINFO_BASETYPES (sc); tree basetype_vec = TYPE_BINFO_BASETYPES (sc);
int n = TREE_VEC_LENGTH (basetype_vec), i; int n = TREE_VEC_LENGTH (basetype_vec), i;
object_done = 1;
for (i = 1; i < n; i++) for (i = 1; i < n; i++)
{ {
tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i)); tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
@ -10190,7 +10173,6 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
list = chainon (rlist, list); list = chainon (rlist, list);
} }
} }
object_done = 0;
} }
/* Search enclosing context of inner classes before looking /* Search enclosing context of inner classes before looking
@ -10211,10 +10193,35 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
else else
class = sc; class = sc;
for (class = (lc ? NULL_TREE : CLASSTYPE_SUPER (class)); /* Search superclass */
class; class = CLASSTYPE_SUPER (class)) if (!lc && CLASSTYPE_SUPER (class) != NULL_TREE)
search_applicable_methods_list (lc, TYPE_METHODS (class), {
name, arglist, &list, &all_list); tree rlist;
class = CLASSTYPE_SUPER (class);
rlist = find_applicable_accessible_methods_list (lc, class,
name, arglist);
list = chainon (rlist, list);
}
}
search_not_done--;
/* 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 /* Either return the list obtained or all selected (but
@ -10222,7 +10229,7 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
return (!list ? all_list : list); return (!list ? all_list : list);
} }
/* Effectively search for the approriate method in method */ /* Effectively search for the appropriate method in method */
static void static void
search_applicable_methods_list (lc, method, name, arglist, list, all_list) search_applicable_methods_list (lc, method, name, arglist, list, all_list)
@ -10251,7 +10258,7 @@ search_applicable_methods_list (lc, method, name, arglist, list, all_list)
*all_list = tree_cons (NULL_TREE, method, *list); *all_list = tree_cons (NULL_TREE, method, *list);
} }
} }
} }
/* 15.11.2.2 Choose the Most Specific Method */ /* 15.11.2.2 Choose the Most Specific Method */