[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
parent c59ff527
...@@ -401,6 +401,7 @@ set_super_info (access_flags, this_class, super_class, interfaces_count) ...@@ -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_ABSTRACT) CLASS_ABSTRACT (class_decl) = 1;
if (access_flags & ACC_STATIC) CLASS_STATIC (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_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, /* Return length of inheritance chain of CLAS, where java.lang.Object is 0,
...@@ -493,7 +494,7 @@ enclosing_context_p (type1, type2) ...@@ -493,7 +494,7 @@ enclosing_context_p (type1, type2)
int common_enclosing_context_p (type1, type2) int common_enclosing_context_p (type1, type2)
tree 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; return 0;
for (type1 = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type1))); type1; for (type1 = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type1))); type1;
...@@ -1075,6 +1076,10 @@ get_access_flags_from_decl (decl) ...@@ -1075,6 +1076,10 @@ get_access_flags_from_decl (decl)
access_flags |= ACC_ABSTRACT; access_flags |= ACC_ABSTRACT;
if (CLASS_STATIC (decl)) if (CLASS_STATIC (decl))
access_flags |= ACC_STATIC; access_flags |= ACC_STATIC;
if (CLASS_PRIVATE (decl))
access_flags |= ACC_PRIVATE;
if (CLASS_PROTECTED (decl))
access_flags |= ACC_PROTECTED;
return access_flags; return access_flags;
} }
if (TREE_CODE (decl) == FUNCTION_DECL) if (TREE_CODE (decl) == FUNCTION_DECL)
......
...@@ -576,6 +576,7 @@ struct lang_decl_var ...@@ -576,6 +576,7 @@ struct lang_decl_var
for non primitive types when compiling to bytecode. */ for non primitive types when compiling to bytecode. */
#define TYPE_DOT_CLASS(T) (TYPE_LANG_SPECIFIC(T)->dot_class) #define TYPE_DOT_CLASS(T) (TYPE_LANG_SPECIFIC(T)->dot_class)
#define TYPE_PRIVATE_INNER_CLASS(T) (TYPE_LANG_SPECIFIC(T)->pic) #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 struct lang_type
{ {
...@@ -591,6 +592,7 @@ struct lang_type ...@@ -591,6 +592,7 @@ struct lang_type
compiling to bytecode to implement compiling to bytecode to implement
<non_primitive_type>.class */ <non_primitive_type>.class */
unsigned pic:1; /* Private Inner Class. */ unsigned pic:1; /* Private Inner Class. */
unsigned poic:1; /* Protected Inner Class. */
}; };
#ifdef JAVA_USE_HANDLES #ifdef JAVA_USE_HANDLES
...@@ -840,6 +842,7 @@ struct rtx_def * java_lang_expand_expr PARAMS ((tree, rtx, enum machine_mode, ...@@ -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_SUPER(DECL) DECL_LANG_FLAG_6 (DECL)
#define CLASS_STATIC(DECL) DECL_LANG_FLAG_7 (DECL) #define CLASS_STATIC(DECL) DECL_LANG_FLAG_7 (DECL)
#define CLASS_PRIVATE(DECL) (TYPE_PRIVATE_INNER_CLASS (TREE_TYPE (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 */ /* @deprecated marker flag on methods, fields and classes */
......
...@@ -5199,7 +5199,8 @@ jdep_resolve_class (dep) ...@@ -5199,7 +5199,8 @@ jdep_resolve_class (dep)
if (!decl) if (!decl)
complete_class_report_errors (dep); 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; return decl;
} }
...@@ -6781,24 +6782,37 @@ lookup_package_type (name, from) ...@@ -6781,24 +6782,37 @@ lookup_package_type (name, from)
} }
static void static void
check_inner_class_access (decl, enclosing_type, cl) check_inner_class_access (decl, enclosing_decl, cl)
tree decl, enclosing_type, cl; tree decl, enclosing_decl, cl;
{ {
if (!decl) int access = 0;
return;
/* We don't issue an error message when CL is null. CL can be null /* We don't issue an error message when CL is null. CL can be null
as a result of processing a JDEP crafted by as a result of processing a JDEP crafted by source_start_java_method
source_start_java_method for the purpose of patching its parm for the purpose of patching its parm decl. But the error would
decl. But the error would have been already trapped when fixing have been already trapped when fixing the method's signature.
the method's signature. */ DECL can also be NULL in case of earlier errors. */
if (!(cl && PURE_INNER_CLASS_DECL_P (decl) && CLASS_PRIVATE (decl)) if (!decl || !cl)
|| (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)))
return; 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"), (CLASS_INTERFACE (decl) ? "interface" : "class"),
lang_printable_name (decl, 0)); lang_printable_name (decl, 0));
} }
...@@ -9001,9 +9015,19 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found) ...@@ -9001,9 +9015,19 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
*where_found = decl = current_this; *where_found = decl = current_this;
*type_found = type = QUAL_DECL_TYPE (decl); *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 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); *where_found = decl = build_current_thisn (type);
from_qualified_this = 1; from_qualified_this = 1;
} }
...@@ -9169,6 +9193,24 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found) ...@@ -9169,6 +9193,24 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
field_decl = lookup_field_wrapper (type, field_decl = lookup_field_wrapper (type,
EXPR_WFL_NODE (qual_wfl)); 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) if (field_decl == NULL_TREE)
{ {
parse_error_context parse_error_context
...@@ -9283,7 +9325,8 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found) ...@@ -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) /* 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 static int
not_accessible_p (reference, member, from_super) not_accessible_p (reference, member, from_super)
...@@ -9292,6 +9335,10 @@ 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); 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 */ /* Access always granted for members declared public */
if (access_flag & ACC_PUBLIC) if (access_flag & ACC_PUBLIC)
return 0; return 0;
...@@ -9310,7 +9357,17 @@ not_accessible_p (reference, member, from_super) ...@@ -9310,7 +9357,17 @@ not_accessible_p (reference, member, from_super)
return 0; return 0;
/* Otherwise, access is granted if occuring from the class where /* 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))) if (inherits_from_p (reference, DECL_CONTEXT (member)))
return 0; return 0;
return 1; return 1;
...@@ -9318,8 +9375,7 @@ not_accessible_p (reference, member, from_super) ...@@ -9318,8 +9375,7 @@ not_accessible_p (reference, member, from_super)
/* Check access on private members. Access is granted only if it /* Check access on private members. Access is granted only if it
occurs from within the class in which it is declared. Exceptions occurs from within the class in which it is declared. Exceptions
are accesses from inner-classes. This section is probably not are accesses from inner-classes. */
complete. FIXME */
if (access_flag & ACC_PRIVATE) if (access_flag & ACC_PRIVATE)
return (current_class == DECL_CONTEXT (member) ? 0 : return (current_class == DECL_CONTEXT (member) ? 0 :
(INNER_CLASS_TYPE_P (current_class) ? 0 : 1)); (INNER_CLASS_TYPE_P (current_class) ? 0 : 1));
...@@ -9643,7 +9699,7 @@ patch_method_invocation (patch, primary, where, is_static, ret_decl) ...@@ -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 maybe_use_access_method returns a non zero value if the
this_arg has to be moved into the (then generated) stub 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. */ might have be replaced by a generated stub. */
if (maybe_use_access_method (is_super_init, &list, &this_arg)) if (maybe_use_access_method (is_super_init, &list, &this_arg))
args = tree_cons (NULL_TREE, this_arg, args); args = tree_cons (NULL_TREE, this_arg, args);
...@@ -9811,7 +9867,7 @@ maybe_use_access_method (is_super_init, mdecl, this_arg) ...@@ -9811,7 +9867,7 @@ maybe_use_access_method (is_super_init, mdecl, this_arg)
if (non_static_context) if (non_static_context)
{ {
ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class))); 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_current_thisn (current_class);
ta = build_wfl_node (ta); ta = build_wfl_node (ta);
...@@ -9822,7 +9878,7 @@ maybe_use_access_method (is_super_init, mdecl, this_arg) ...@@ -9822,7 +9878,7 @@ maybe_use_access_method (is_super_init, mdecl, this_arg)
while (type) while (type)
{ {
maybe_build_thisn_access_method (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); ta = build_access_to_thisn (ctx, type, 0);
break; break;
......
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