From 9c5fdae6338380b3dd9d98c9540fb69c242baae7 Mon Sep 17 00:00:00 2001 From: Bryce McKinlay Date: Tue, 29 Jun 2004 17:58:44 +0000 Subject: [PATCH] re PR java/1262 (Method with default access can be overridden in another package) PR java/1262 * class.c (layout_class_method): Do not override package-private method if its in a different package. (split_qualified_name): Move here from parse.y. Rename from breakdown_qualified. Add comment. (in_same_package): Move here from parse.y. Add comment. * java-tree.h (break_down_qualified, in_same_package): Declare. (in_same_package): Likewise. * parse.y (breakdown_qualified, in_same_package): Moved to class.c. Callers updated. From-SVN: r83867 --- gcc/java/ChangeLog | 13 ++++++++ gcc/java/class.c | 76 +++++++++++++++++++++++++++++++++++++++++++- gcc/java/java-tree.h | 3 ++ gcc/java/parse.y | 64 +++---------------------------------- 4 files changed, 95 insertions(+), 61 deletions(-) diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 51a2b359bce..0544670b65c 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,16 @@ +2004-06-29 Bryce McKinlay + + PR java/1262 + * class.c (layout_class_method): Do not override package-private + method if its in a different package. + (split_qualified_name): Move here from parse.y. Rename from + breakdown_qualified. Add comment. + (in_same_package): Move here from parse.y. Add comment. + * java-tree.h (break_down_qualified, in_same_package): Declare. + (in_same_package): Likewise. + * parse.y (breakdown_qualified, in_same_package): Moved to class.c. + Callers updated. + 2004-06-29 Andrew Haley * except.c (expand_start_java_handler): Push a new binding level. diff --git a/gcc/java/class.c b/gcc/java/class.c index a9852d5d85e..03b18286aa4 100644 --- a/gcc/java/class.c +++ b/gcc/java/class.c @@ -2214,9 +2214,24 @@ layout_class_method (tree this_class, tree super_class, { tree method_sig = build_java_argument_signature (TREE_TYPE (method_decl)); + bool method_override = false; tree super_method = lookup_argument_method (super_class, method_name, method_sig); - if (super_method != NULL_TREE && ! METHOD_PRIVATE (super_method)) + if (super_method != NULL_TREE) + { + method_override = true; + if (! METHOD_PUBLIC (super_method) && + ! METHOD_PROTECTED (super_method)) + { + /* Don't override private method, or default-access method in + another package. */ + if (METHOD_PRIVATE (super_method) || + ! in_same_package (TYPE_NAME (this_class), + TYPE_NAME (super_class))) + method_override = false; + } + } + if (method_override) { tree method_index = get_method_index (super_method); set_method_index (method_decl, method_index); @@ -2538,4 +2553,63 @@ java_treetreehash_create (size_t size, int gc) java_treetreehash_compare, free, xcalloc, free); } +/* Break down qualified IDENTIFIER into package and class-name components. + For example, given SOURCE "pkg.foo.Bar", LEFT will be set to + "pkg.foo", and RIGHT to "Bar". */ + +int +split_qualified_name (tree *left, tree *right, tree source) +{ + char *p, *base; + int l = IDENTIFIER_LENGTH (source); + + base = alloca (l + 1); + memcpy (base, IDENTIFIER_POINTER (source), l + 1); + + /* Breakdown NAME into REMAINDER . IDENTIFIER. */ + p = base + l - 1; + while (*p != '.' && p != base) + p--; + + /* We didn't find a '.'. Return an error. */ + if (p == base) + return 1; + + *p = '\0'; + if (right) + *right = get_identifier (p+1); + *left = get_identifier (base); + + return 0; +} + +/* Given two classes (TYPE_DECL) or class names (IDENTIFIER), return TRUE + if the classes are from the same package. */ + +int +in_same_package (tree name1, tree name2) +{ + tree tmp; + tree pkg1; + tree pkg2; + + if (TREE_CODE (name1) == TYPE_DECL) + name1 = DECL_NAME (name1); + if (TREE_CODE (name2) == TYPE_DECL) + name2 = DECL_NAME (name2); + + if (QUALIFIED_P (name1) != QUALIFIED_P (name2)) + /* One in empty package. */ + return 0; + + if (QUALIFIED_P (name1) == 0 && QUALIFIED_P (name2) == 0) + /* Both in empty package. */ + return 1; + + split_qualified_name (&pkg1, &tmp, name1); + split_qualified_name (&pkg2, &tmp, name2); + + return (pkg1 == pkg2); +} + #include "gt-java-class.h" diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h index 1089e595083..be9a64d2630 100644 --- a/gcc/java/java-tree.h +++ b/gcc/java/java-tree.h @@ -1359,6 +1359,9 @@ extern tree make_catch_class_record (tree, tree); extern tree emit_catch_table (tree); extern void gen_indirect_dispatch_tables (tree type); +extern int split_qualified_name (tree *left, tree *right, tree source); +extern int in_same_package (tree, tree); + #define DECL_FINAL(DECL) DECL_LANG_FLAG_3 (DECL) diff --git a/gcc/java/parse.y b/gcc/java/parse.y index 7f886707736..adac725cd17 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -122,8 +122,6 @@ static tree resolve_expression_name (tree, tree *); static tree maybe_create_class_interface_decl (tree, tree, tree, tree); static int check_class_interface_creation (int, int, tree, tree, tree, tree); static tree patch_method_invocation (tree, tree, tree, int, int *, tree *); -static int breakdown_qualified (tree *, tree *, tree); -static int in_same_package (tree, tree); static tree resolve_and_layout (tree, tree); static tree qualify_and_find (tree, tree, tree); static tree resolve_no_layout (tree, tree); @@ -5744,7 +5742,7 @@ do_resolve_class (tree enclosing, tree class_type, tree decl, tree cl) class and then treat Id as a member type. If we can't find Q as a class then we fall through. */ tree q, left, left_type, right; - if (breakdown_qualified (&left, &right, TYPE_NAME (class_type)) == 0) + if (split_qualified_name (&left, &right, TYPE_NAME (class_type)) == 0) { BUILD_PTR_FROM_NAME (left_type, left); q = do_resolve_class (enclosing, left_type, decl, cl); @@ -6823,7 +6821,7 @@ process_imports (void) inner class. The only way for us to know is to try again after having dropped a qualifier. If we can't break it further, we have an error. */ - if (breakdown_qualified (&left, NULL, to_be_found)) + if (split_qualified_name (&left, NULL, to_be_found)) break; to_be_found = left; @@ -7257,7 +7255,7 @@ check_pkg_class_access (tree class_name, tree cl, bool verbose, tree this_decl) /* Access to a private class within the same package is allowed. */ tree l, r; - breakdown_qualified (&l, &r, class_name); + split_qualified_name (&l, &r, class_name); if (!QUALIFIED_P (class_name) && !ctxp->package) /* Both in the empty package. */ return 0; @@ -10193,7 +10191,7 @@ class_in_current_package (tree class) return 1; /* Compare the left part of the name of CLASS with the package name */ - breakdown_qualified (&left, NULL, DECL_NAME (TYPE_NAME (class))); + split_qualified_name (&left, NULL, DECL_NAME (TYPE_NAME (class))); if (ctxp->package == left) { cicp_cache = class; @@ -11345,60 +11343,6 @@ qualify_ambiguous_name (tree id) RESOLVE_PACKAGE_NAME_P (id) = 1; } -static int -breakdown_qualified (tree *left, tree *right, tree source) -{ - char *p, *base; - int l = IDENTIFIER_LENGTH (source); - - base = alloca (l + 1); - memcpy (base, IDENTIFIER_POINTER (source), l + 1); - - /* Breakdown NAME into REMAINDER . IDENTIFIER. */ - p = base + l - 1; - while (*p != '.' && p != base) - p--; - - /* We didn't find a '.'. Return an error. */ - if (p == base) - return 1; - - *p = '\0'; - if (right) - *right = get_identifier (p+1); - *left = get_identifier (base); - - return 0; -} - -/* Return TRUE if two classes are from the same package. */ - -static int -in_same_package (tree name1, tree name2) -{ - tree tmp; - tree pkg1; - tree pkg2; - - if (TREE_CODE (name1) == TYPE_DECL) - name1 = DECL_NAME (name1); - if (TREE_CODE (name2) == TYPE_DECL) - name2 = DECL_NAME (name2); - - if (QUALIFIED_P (name1) != QUALIFIED_P (name2)) - /* One in empty package. */ - return 0; - - if (QUALIFIED_P (name1) == 0 && QUALIFIED_P (name2) == 0) - /* Both in empty package. */ - return 1; - - breakdown_qualified (&pkg1, &tmp, name1); - breakdown_qualified (&pkg2, &tmp, name2); - - return (pkg1 == pkg2); -} - /* Patch tree nodes in a function body. When a BLOCK is found, push local variable decls if present. Same as java_complete_lhs, but does resolve static finals to values. */ -- 2.30.2