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
This commit is contained in:
Bryce McKinlay 2004-06-29 17:58:44 +00:00 committed by Bryce McKinlay
parent 4961683533
commit 9c5fdae633
4 changed files with 95 additions and 61 deletions

View file

@ -1,3 +1,16 @@
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>
* except.c (expand_start_java_handler): Push a new binding level.

View file

@ -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"

View file

@ -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)

View file

@ -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. */