From ddfacdaddec5af1b0e9bfd76f810c5127e166ac5 Mon Sep 17 00:00:00 2001 From: bryce Date: Thu, 7 Jul 2005 14:43:59 +0000 Subject: [PATCH 1/1] 2005-07-07 Bryce McKinlay PR java/18119 * parse.y (inner_class_accessible): New function. Logic moved from check_inner_class_access. (check_inner_class_access): Use inner_class_accessible. (resolve_inner_class): Simplify arguments. Create circularity hash here. Keep looking for classes if we found one that was inaccessible. Return the inaccessible class only if there is no other match. (do_resolve_class): Update for new resolve_inner_class arguments. Don't create circularity_hash here. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@101715 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/java/ChangeLog | 12 ++ gcc/java/parse.y | 176 ++++++++++++++++------------ libjava/ChangeLog | 5 + libjava/testsuite/libjava.jacks/jacks.xfail | 4 - 4 files changed, 116 insertions(+), 81 deletions(-) diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 88284867b65..2e0fecd5465 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,5 +1,17 @@ 2005-07-07 Bryce McKinlay + PR java/18119 + * parse.y (inner_class_accessible): New function. Logic moved from + check_inner_class_access. + (check_inner_class_access): Use inner_class_accessible. + (resolve_inner_class): Simplify arguments. Create circularity hash + here. Keep looking for classes if we found one that was inaccessible. + Return the inaccessible class only if there is no other match. + (do_resolve_class): Update for new resolve_inner_class arguments. + Don't create circularity_hash here. + +2005-07-07 Bryce McKinlay + PR java/21045 * parse.y (add_exception_to_throws): New function. (purge_unchecked_exceptions): Removed. diff --git a/gcc/java/parse.y b/gcc/java/parse.y index 9a094e5d61b..6007b18a11d 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -112,6 +112,7 @@ static int process_imports (void); static void read_import_dir (tree); static int find_in_imports_on_demand (tree, tree); static void find_in_imports (tree, tree); +static bool inner_class_accessible (tree, tree); static void check_inner_class_access (tree, tree, tree); static int check_pkg_class_access (tree, tree, bool, tree); static tree resolve_package (tree, tree *, tree *); @@ -311,7 +312,7 @@ static int pop_current_osb (struct parser_ctxt *); static tree maybe_make_nested_class_name (tree); static int make_nested_class_name (tree); static void link_nested_class_to_enclosing (void); -static tree resolve_inner_class (htab_t, tree, tree *, tree *, tree); +static tree resolve_inner_class (tree, tree, tree, tree); static tree find_as_inner_class (tree, tree, tree); static tree find_as_inner_class_do (tree, tree); static int check_inner_class_redefinition (tree, tree); @@ -3663,46 +3664,52 @@ check_inner_class_redefinition (tree raw_name, tree cl) return 0; } -/* Tries to find a decl for CLASS_TYPE within ENCLOSING. If we fail, - we remember ENCLOSING and SUPER. */ +/* Tries to find a decl for CLASS_TYPE within ENCLOSING. May return an + invisible/non-accessible matching decl when an accessible one could not be + found, in order to give a better error message when accessibility is + checked later. */ static tree -resolve_inner_class (htab_t circularity_hash, tree cl, tree *enclosing, - tree *super, tree class_type) +resolve_inner_class (tree context, tree cl, tree enclosing, tree class_type) { - tree local_enclosing = *enclosing; tree local_super = NULL_TREE; + tree candidate = NULL_TREE; - while (local_enclosing) + /* This hash table is used to register the classes we're going + through when searching the current class as an inner class, in + order to detect circular references. */ + htab_t circularity_hash = htab_create (20, htab_hash_pointer, htab_eq_pointer, + NULL); + + while (enclosing) { - tree intermediate, decl; + tree decl; - *htab_find_slot (circularity_hash, local_enclosing, INSERT) = - local_enclosing; + *htab_find_slot (circularity_hash, enclosing, INSERT) = enclosing; - if ((decl = find_as_inner_class (local_enclosing, class_type, cl))) - return decl; - - intermediate = local_enclosing; - /* Explore enclosing contexts. */ - while (INNER_CLASS_DECL_P (intermediate)) - { - intermediate = DECL_CONTEXT (intermediate); - if ((decl = find_as_inner_class (intermediate, class_type, cl))) - return decl; - } + if ((decl = find_as_inner_class (enclosing, class_type, cl))) + { + if (inner_class_accessible (decl, context)) + { + candidate = decl; + break; + } + else + if (candidate == NULL_TREE) + candidate = decl; + } /* Now go to the upper classes, bail out if necessary. We will analyze the returned SUPER and act accordingly (see do_resolve_class). */ - if (JPRIMITIVE_TYPE_P (TREE_TYPE (local_enclosing)) - || TREE_TYPE (local_enclosing) == void_type_node) + if (JPRIMITIVE_TYPE_P (TREE_TYPE (enclosing)) + || TREE_TYPE (enclosing) == void_type_node) { parse_error_context (cl, "Qualifier must be a reference"); - local_enclosing = NULL_TREE; + enclosing = NULL_TREE; break; } - local_super = CLASSTYPE_SUPER (TREE_TYPE (local_enclosing)); + local_super = CLASSTYPE_SUPER (TREE_TYPE (enclosing)); if (!local_super || local_super == object_type_node) break; @@ -3716,22 +3723,22 @@ resolve_inner_class (htab_t circularity_hash, tree cl, tree *enclosing, if (htab_find (circularity_hash, local_super) != NULL) { if (!cl) - cl = lookup_cl (local_enclosing); + cl = lookup_cl (enclosing); parse_error_context (cl, "Cyclic inheritance involving %s", - IDENTIFIER_POINTER (DECL_NAME (local_enclosing))); - local_enclosing = NULL_TREE; + IDENTIFIER_POINTER (DECL_NAME (enclosing))); + enclosing = NULL_TREE; } else - local_enclosing = local_super; + enclosing = local_super; } - /* We failed. Return LOCAL_SUPER and LOCAL_ENCLOSING. */ - *super = local_super; - *enclosing = local_enclosing; + htab_delete (circularity_hash); - return NULL_TREE; + /* We failed, but we might have found a matching class that wasn't + accessible. Return that to get a better error message. */ + return candidate; } /* Within ENCLOSING, find a decl for NAME and return it. NAME can be @@ -5866,10 +5873,10 @@ tree do_resolve_class (tree enclosing, tree import_type, tree class_type, tree decl, tree cl) { - tree new_class_decl = NULL_TREE, super = NULL_TREE; + tree new_class_decl = NULL_TREE; tree saved_enclosing_type = enclosing ? TREE_TYPE (enclosing) : NULL_TREE; + tree candidate = NULL_TREE; tree decl_result; - htab_t circularity_hash; if (QUALIFIED_P (TYPE_NAME (class_type))) { @@ -5893,12 +5900,7 @@ do_resolve_class (tree enclosing, tree import_type, tree class_type, tree decl, if (enclosing) { - /* This hash table is used to register the classes we're going - through when searching the current class as an inner class, in - order to detect circular references. Remember to free it before - returning the section 0- of this function. */ - circularity_hash = htab_create (20, htab_hash_pointer, htab_eq_pointer, - NULL); + tree context = enclosing; /* 0- Search in the current class as an inner class. Maybe some code here should be added to load the class or @@ -5906,22 +5908,23 @@ do_resolve_class (tree enclosing, tree import_type, tree class_type, tree decl, being loaded from class file. FIXME. */ while (enclosing) { - new_class_decl = resolve_inner_class (circularity_hash, cl, &enclosing, - &super, class_type); + new_class_decl = resolve_inner_class (context, cl, enclosing, class_type); + if (new_class_decl) - break; + { + if (inner_class_accessible (new_class_decl, context)) + break; + else + if (candidate == NULL_TREE) + candidate = new_class_decl; + new_class_decl = NULL_TREE; + } - /* If we haven't found anything because SUPER reached Object and - ENCLOSING happens to be an innerclass, try the enclosing context. */ - if ((!super || super == object_type_node) && - enclosing && INNER_CLASS_DECL_P (enclosing)) - enclosing = DECL_CONTEXT (enclosing); - else - enclosing = NULL_TREE; + /* Now that we've looked through all superclasses, try the enclosing + context. */ + enclosing = DECL_CONTEXT (enclosing); } - htab_delete (circularity_hash); - if (new_class_decl) return new_class_decl; } @@ -6007,7 +6010,10 @@ do_resolve_class (tree enclosing, tree import_type, tree class_type, tree decl, } } while (!decl_result && separator); } - return decl_result; + if (decl_result) + return decl_result; + else + return candidate; } static tree @@ -7263,25 +7269,14 @@ resolve_package (tree pkg, tree *next, tree *type_name) return decl; } +/* Check accessibility of inner class DECL, from the context ENCLOSING_DECL, + according to member access rules. */ -/* Check accessibility of inner classes according to member access rules. - DECL is the inner class, ENCLOSING_DECL is the class from which the - access is being attempted. */ - -static void -check_inner_class_access (tree decl, tree enclosing_decl, tree cl) +static bool +inner_class_accessible (tree decl, tree enclosing_decl) { - const char *access; tree enclosing_decl_type; - /* We don't issue an error message when CL is null. CL can be null - as a result of processing a JDEP crafted by source_start_java_method - for the purpose of patching its parm decl. But the error would - have been already trapped when fixing the method's signature. - DECL can also be NULL in case of earlier errors. */ - if (!decl || !cl) - return; - enclosing_decl_type = TREE_TYPE (enclosing_decl); if (CLASS_PRIVATE (decl)) @@ -7294,15 +7289,14 @@ check_inner_class_access (tree decl, tree enclosing_decl, tree cl) while (DECL_CONTEXT (enclosing_decl)) enclosing_decl = DECL_CONTEXT (enclosing_decl); if (top_level == enclosing_decl) - return; - access = "private"; + return true; } else if (CLASS_PROTECTED (decl)) { tree decl_context; /* Access is permitted from within the same package... */ if (in_same_package (decl, enclosing_decl)) - return; + return true; /* ... or from within the body of a subtype of the context in which DECL is declared. */ @@ -7313,30 +7307,58 @@ check_inner_class_access (tree decl, tree enclosing_decl, tree cl) { if (interface_of_p (TREE_TYPE (decl_context), enclosing_decl_type)) - return; + return true; } else { /* Eww. The order of the arguments is different!! */ if (inherits_from_p (enclosing_decl_type, TREE_TYPE (decl_context))) - return; + return true; } enclosing_decl = DECL_CONTEXT (enclosing_decl); } - access = "protected"; } else if (! CLASS_PUBLIC (decl)) { /* Access is permitted only from within the same package as DECL. */ if (in_same_package (decl, enclosing_decl)) - return; - access = "non-public"; + return true; } else /* Class is public. */ + return true; + + return false; +} + +/* Check accessibility of inner classes according to member access rules. + DECL is the inner class, ENCLOSING_DECL is the class from which the + access is being attempted. */ + +static void +check_inner_class_access (tree decl, tree enclosing_decl, tree cl) +{ + const char *access; + + /* We don't issue an error message when CL is null. CL can be null + as a result of processing a JDEP crafted by source_start_java_method + for the purpose of patching its parm decl. But the error would + have been already trapped when fixing the method's signature. + DECL can also be NULL in case of earlier errors. */ + if (!decl || !cl) return; + if (inner_class_accessible (decl, enclosing_decl)) + return; + + if (CLASS_PRIVATE (decl)) + access = "private"; + else if (CLASS_PROTECTED (decl)) + access = "protected"; + else + access = "non-public"; + parse_error_context (cl, "Nested %s %s is %s; cannot be accessed from here", (CLASS_INTERFACE (decl) ? "interface" : "class"), lang_printable_name (decl, 2), access); diff --git a/libjava/ChangeLog b/libjava/ChangeLog index e0825bbc4ea..4e173ee8c16 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,5 +1,10 @@ 2005-07-07 Bryce McKinlay + * testsuite/libjava.jacks/jacks.xfail: Remove 6.5.5.1-nested-4, + 6.5.5.1-nested-7, 6.5.5.1-nested-16, 6.5.5.1-nested-17. + +2005-07-07 Bryce McKinlay + * testsuite/libjava.compile/PR21045.java: New test. * testsuite/libjava.jacks/jacks.xfail: Remove 15.9.5.1-exception-1, 15.9.5.1-exception-3, 8.3.2-abrupt-6, 8.3.2-abrupt-7. diff --git a/libjava/testsuite/libjava.jacks/jacks.xfail b/libjava/testsuite/libjava.jacks/jacks.xfail index 68af018a5f4..0472b55a26d 100644 --- a/libjava/testsuite/libjava.jacks/jacks.xfail +++ b/libjava/testsuite/libjava.jacks/jacks.xfail @@ -466,14 +466,10 @@ 6.5.5.1-import-2 6.5.5.1-import-3 6.5.5.1-nested-14 -6.5.5.1-nested-16 -6.5.5.1-nested-17 6.5.5.1-nested-19 6.5.5.1-nested-20 6.5.5.1-nested-21 6.5.5.1-nested-23 -6.5.5.1-nested-4 -6.5.5.1-nested-7 6.5.5.1-nested-8 6.5.5.1-nested-9 6.5.5.2-type-4 -- 2.11.0