Commit 9c5fdae6 by Bryce McKinlay Committed by Bryce McKinlay

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
parent 49616835
2004-06-29 Bryce McKinlay <mckinlay@redhat.com>
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 <aph@redhat.com> 2004-06-29 Andrew Haley <aph@redhat.com>
* except.c (expand_start_java_handler): Push a new binding level. * except.c (expand_start_java_handler): Push a new binding level.
......
...@@ -2214,9 +2214,24 @@ layout_class_method (tree this_class, tree super_class, ...@@ -2214,9 +2214,24 @@ layout_class_method (tree this_class, tree super_class,
{ {
tree method_sig = tree method_sig =
build_java_argument_signature (TREE_TYPE (method_decl)); build_java_argument_signature (TREE_TYPE (method_decl));
bool method_override = false;
tree super_method = lookup_argument_method (super_class, method_name, tree super_method = lookup_argument_method (super_class, method_name,
method_sig); 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); tree method_index = get_method_index (super_method);
set_method_index (method_decl, method_index); set_method_index (method_decl, method_index);
...@@ -2538,4 +2553,63 @@ java_treetreehash_create (size_t size, int gc) ...@@ -2538,4 +2553,63 @@ java_treetreehash_create (size_t size, int gc)
java_treetreehash_compare, free, xcalloc, free); 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" #include "gt-java-class.h"
...@@ -1359,6 +1359,9 @@ extern tree make_catch_class_record (tree, tree); ...@@ -1359,6 +1359,9 @@ extern tree make_catch_class_record (tree, tree);
extern tree emit_catch_table (tree); extern tree emit_catch_table (tree);
extern void gen_indirect_dispatch_tables (tree type); 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) #define DECL_FINAL(DECL) DECL_LANG_FLAG_3 (DECL)
......
...@@ -122,8 +122,6 @@ static tree resolve_expression_name (tree, tree *); ...@@ -122,8 +122,6 @@ static tree resolve_expression_name (tree, tree *);
static tree maybe_create_class_interface_decl (tree, tree, 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 int check_class_interface_creation (int, int, tree, tree, tree, tree);
static tree patch_method_invocation (tree, tree, tree, int, int *, 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 resolve_and_layout (tree, tree);
static tree qualify_and_find (tree, tree, tree); static tree qualify_and_find (tree, tree, tree);
static tree resolve_no_layout (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) ...@@ -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 class and then treat Id as a member type. If we can't find Q
as a class then we fall through. */ as a class then we fall through. */
tree q, left, left_type, right; 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); BUILD_PTR_FROM_NAME (left_type, left);
q = do_resolve_class (enclosing, left_type, decl, cl); q = do_resolve_class (enclosing, left_type, decl, cl);
...@@ -6823,7 +6821,7 @@ process_imports (void) ...@@ -6823,7 +6821,7 @@ process_imports (void)
inner class. The only way for us to know is to try again 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, after having dropped a qualifier. If we can't break it further,
we have an error. */ we have an error. */
if (breakdown_qualified (&left, NULL, to_be_found)) if (split_qualified_name (&left, NULL, to_be_found))
break; break;
to_be_found = left; to_be_found = left;
...@@ -7257,7 +7255,7 @@ check_pkg_class_access (tree class_name, tree cl, bool verbose, tree this_decl) ...@@ -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 /* Access to a private class within the same package is
allowed. */ allowed. */
tree l, r; tree l, r;
breakdown_qualified (&l, &r, class_name); split_qualified_name (&l, &r, class_name);
if (!QUALIFIED_P (class_name) && !ctxp->package) if (!QUALIFIED_P (class_name) && !ctxp->package)
/* Both in the empty package. */ /* Both in the empty package. */
return 0; return 0;
...@@ -10193,7 +10191,7 @@ class_in_current_package (tree class) ...@@ -10193,7 +10191,7 @@ class_in_current_package (tree class)
return 1; return 1;
/* Compare the left part of the name of CLASS with the package name */ /* 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) if (ctxp->package == left)
{ {
cicp_cache = class; cicp_cache = class;
...@@ -11345,60 +11343,6 @@ qualify_ambiguous_name (tree id) ...@@ -11345,60 +11343,6 @@ qualify_ambiguous_name (tree id)
RESOLVE_PACKAGE_NAME_P (id) = 1; 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 /* Patch tree nodes in a function body. When a BLOCK is found, push
local variable decls if present. local variable decls if present.
Same as java_complete_lhs, but does resolve static finals to values. */ Same as java_complete_lhs, but does resolve static finals to values. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment