[multiple changes]

2000-07-13  Alexandre Petit-Bianco  <apbianco@cygnus.com>

	* parse.y (patch_method_invocation): Fixed comment.
	(maybe_use_access_method): Build this$<n>s to the context of the
	target method, or a type that extends it. Fixes gcj/242.

2000-07-13  Alexandre Petit-Bianco  <apbianco@cygnus.com>

	* parse.y (not_accessible_p): Access granted to innerclasses
	(indirectly) extending the reference type. Fixes gcj/249.

2000-07-10  Alexandre Petit-Bianco  <apbianco@cygnus.com>

	* parse.y (resolve_qualified_expression_name): Verify qualified
	access to `this.' Fixes gcj/239.

2000-07-10  Alexandre Petit-Bianco  <apbianco@cygnus.com>

	* class.c (set_super_info): Handled protected inner classes.
	(common_enclosing_context_p): Bail early if arguments aren't both
	inner classes.
	(get_access_flags_from_decl): Handle private and protected inner
	classes.
	* java-tree.h (TYPE_PROTECTED_INNER_CLASS): New macro.
	(CLASS_PROTECTED): Likewise.
	(struct lang_type): New bitfield `poic.'
	* parse.y (jdep_resolve_class): Call check_inner_class_access on
	inner classes only.
	(check_inner_class_access): Renamed arguments, added
	comments. Handles protected inner classes (fixes gcj/225)
	(not_accessible_p): Fixed comments. Avoid handling inner classes.

2000-07-07  Alexandre Petit-Bianco  <apbianco@cygnus.com>

	* parse.y (resolve_qualified_expression_name): Handle inner class
	access. Fixes gcj/256.

(Fixes gcj/242, gcj/249, gcj/239, gcj/225 and gcj/256:
 http://gcc.gnu.org/ml/gcc-patches/2000-07/msg00801.html)

From-SVN: r35156
This commit is contained in:
Alexandre Petit-Bianco 2000-07-20 17:01:43 -07:00
parent c59ff527c5
commit 4dbf449657
3 changed files with 88 additions and 24 deletions

View File

@ -401,6 +401,7 @@ set_super_info (access_flags, this_class, super_class, interfaces_count)
if (access_flags & ACC_ABSTRACT) CLASS_ABSTRACT (class_decl) = 1;
if (access_flags & ACC_STATIC) CLASS_STATIC (class_decl) = 1;
if (access_flags & ACC_PRIVATE) CLASS_PRIVATE (class_decl) = 1;
if (access_flags & ACC_PROTECTED) CLASS_PROTECTED (class_decl) = 1;
}
/* Return length of inheritance chain of CLAS, where java.lang.Object is 0,
@ -493,7 +494,7 @@ enclosing_context_p (type1, type2)
int common_enclosing_context_p (type1, type2)
tree type1, type2;
{
if (!PURE_INNER_CLASS_TYPE_P (type1) && !PURE_INNER_CLASS_TYPE_P (type2))
if (!PURE_INNER_CLASS_TYPE_P (type1) || !PURE_INNER_CLASS_TYPE_P (type2))
return 0;
for (type1 = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type1))); type1;
@ -1075,6 +1076,10 @@ get_access_flags_from_decl (decl)
access_flags |= ACC_ABSTRACT;
if (CLASS_STATIC (decl))
access_flags |= ACC_STATIC;
if (CLASS_PRIVATE (decl))
access_flags |= ACC_PRIVATE;
if (CLASS_PROTECTED (decl))
access_flags |= ACC_PROTECTED;
return access_flags;
}
if (TREE_CODE (decl) == FUNCTION_DECL)

View File

@ -576,6 +576,7 @@ struct lang_decl_var
for non primitive types when compiling to bytecode. */
#define TYPE_DOT_CLASS(T) (TYPE_LANG_SPECIFIC(T)->dot_class)
#define TYPE_PRIVATE_INNER_CLASS(T) (TYPE_LANG_SPECIFIC(T)->pic)
#define TYPE_PROTECTED_INNER_CLASS(T) (TYPE_LANG_SPECIFIC(T)->poic)
struct lang_type
{
@ -591,6 +592,7 @@ struct lang_type
compiling to bytecode to implement
<non_primitive_type>.class */
unsigned pic:1; /* Private Inner Class. */
unsigned poic:1; /* Protected Inner Class. */
};
#ifdef JAVA_USE_HANDLES
@ -840,6 +842,7 @@ struct rtx_def * java_lang_expand_expr PARAMS ((tree, rtx, enum machine_mode,
#define CLASS_SUPER(DECL) DECL_LANG_FLAG_6 (DECL)
#define CLASS_STATIC(DECL) DECL_LANG_FLAG_7 (DECL)
#define CLASS_PRIVATE(DECL) (TYPE_PRIVATE_INNER_CLASS (TREE_TYPE (DECL)))
#define CLASS_PROTECTED(DECL) (TYPE_PROTECTED_INNER_CLASS (TREE_TYPE (DECL)))
/* @deprecated marker flag on methods, fields and classes */

View File

@ -5199,7 +5199,8 @@ jdep_resolve_class (dep)
if (!decl)
complete_class_report_errors (dep);
check_inner_class_access (decl, JDEP_ENCLOSING (dep), JDEP_WFL (dep));
if (PURE_INNER_CLASS_DECL_P (decl))
check_inner_class_access (decl, JDEP_ENCLOSING (dep), JDEP_WFL (dep));
return decl;
}
@ -6781,24 +6782,37 @@ lookup_package_type (name, from)
}
static void
check_inner_class_access (decl, enclosing_type, cl)
tree decl, enclosing_type, cl;
check_inner_class_access (decl, enclosing_decl, cl)
tree decl, enclosing_decl, cl;
{
if (!decl)
return;
int access = 0;
/* 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. */
if (!(cl && PURE_INNER_CLASS_DECL_P (decl) && CLASS_PRIVATE (decl))
|| (PURE_INNER_CLASS_DECL_P (enclosing_type)
&& common_enclosing_context_p (TREE_TYPE (enclosing_type),
TREE_TYPE (decl)))
|| enclosing_context_p (TREE_TYPE (enclosing_type), TREE_TYPE (decl)))
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;
parse_error_context (cl, "Can't access nested %s %s. Only public classes and interfaces in other packages can be accessed",
/* We grant access to private and protected inner classes if the
location from where we're trying to access DECL is an enclosing
context for DECL or if both have a common enclosing context. */
if (CLASS_PRIVATE (decl))
access = 1;
if (CLASS_PROTECTED (decl))
access = 2;
if (!access)
return;
if (common_enclosing_context_p (TREE_TYPE (enclosing_decl),
TREE_TYPE (decl))
|| enclosing_context_p (TREE_TYPE (enclosing_decl),
TREE_TYPE (decl)))
return;
parse_error_context (cl, "Can't access %s nested %s %s. Only public classes and interfaces in other packages can be accessed",
(access == 1 ? "private" : "protected"),
(CLASS_INTERFACE (decl) ? "interface" : "class"),
lang_printable_name (decl, 0));
}
@ -9001,9 +9015,19 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
*where_found = decl = current_this;
*type_found = type = QUAL_DECL_TYPE (decl);
}
/* We're trying to access the this from somewhere else... */
/* We're trying to access the this from somewhere else. Make sure
it's allowed before doing so. */
else
{
if (!enclosing_context_p (type, current_class))
{
char *p = xstrdup (lang_printable_name (type, 0));
parse_error_context (qual_wfl, "Can't use variable `%s.this': type `%s' isn't an outer type of type `%s'",
p, p,
lang_printable_name (current_class, 0));
free (p);
return 1;
}
*where_found = decl = build_current_thisn (type);
from_qualified_this = 1;
}
@ -9169,6 +9193,24 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
field_decl = lookup_field_wrapper (type,
EXPR_WFL_NODE (qual_wfl));
/* Maybe what we're trying to access an inner class. */
if (!field_decl)
{
tree ptr, inner_decl;
BUILD_PTR_FROM_NAME (ptr, EXPR_WFL_NODE (qual_wfl));
inner_decl = resolve_class (decl, ptr, NULL_TREE, qual_wfl);
if (inner_decl)
{
check_inner_class_access (inner_decl, decl, qual_wfl);
type = TREE_TYPE (inner_decl);
decl = inner_decl;
from_type = 1;
continue;
}
}
if (field_decl == NULL_TREE)
{
parse_error_context
@ -9283,7 +9325,8 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
}
/* 6.6 Qualified name and access control. Returns 1 if MEMBER (a decl)
can't be accessed from REFERENCE (a record type). */
can't be accessed from REFERENCE (a record type). This should be
used when decl is a field or a method.*/
static int
not_accessible_p (reference, member, from_super)
@ -9292,6 +9335,10 @@ not_accessible_p (reference, member, from_super)
{
int access_flag = get_access_flags_from_decl (member);
/* Inner classes are processed by check_inner_class_access */
if (INNER_CLASS_TYPE_P (reference))
return 0;
/* Access always granted for members declared public */
if (access_flag & ACC_PUBLIC)
return 0;
@ -9310,7 +9357,17 @@ not_accessible_p (reference, member, from_super)
return 0;
/* Otherwise, access is granted if occuring from the class where
member is declared or a subclass of it */
member is declared or a subclass of it. Find the right
context to perform the check */
if (PURE_INNER_CLASS_TYPE_P (reference))
{
while (INNER_CLASS_TYPE_P (reference))
{
if (inherits_from_p (reference, DECL_CONTEXT (member)))
return 0;
reference = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (reference)));
}
}
if (inherits_from_p (reference, DECL_CONTEXT (member)))
return 0;
return 1;
@ -9318,8 +9375,7 @@ not_accessible_p (reference, member, from_super)
/* Check access on private members. Access is granted only if it
occurs from within the class in which it is declared. Exceptions
are accesses from inner-classes. This section is probably not
complete. FIXME */
are accesses from inner-classes. */
if (access_flag & ACC_PRIVATE)
return (current_class == DECL_CONTEXT (member) ? 0 :
(INNER_CLASS_TYPE_P (current_class) ? 0 : 1));
@ -9643,7 +9699,7 @@ patch_method_invocation (patch, primary, where, is_static, ret_decl)
maybe_use_access_method returns a non zero value if the
this_arg has to be moved into the (then generated) stub
argument list. In the mean time, the selected function
argument list. In the meantime, the selected function
might have be replaced by a generated stub. */
if (maybe_use_access_method (is_super_init, &list, &this_arg))
args = tree_cons (NULL_TREE, this_arg, args);
@ -9811,7 +9867,7 @@ maybe_use_access_method (is_super_init, mdecl, this_arg)
if (non_static_context)
{
ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
if (ctx == DECL_CONTEXT (md))
if (inherits_from_p (ctx, DECL_CONTEXT (md)))
{
ta = build_current_thisn (current_class);
ta = build_wfl_node (ta);
@ -9822,7 +9878,7 @@ maybe_use_access_method (is_super_init, mdecl, this_arg)
while (type)
{
maybe_build_thisn_access_method (type);
if (type == DECL_CONTEXT (md))
if (inherits_from_p (type, DECL_CONTEXT (md)))
{
ta = build_access_to_thisn (ctx, type, 0);
break;