mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-21 08:40:30 +08:00
[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:
parent
c59ff527c5
commit
4dbf449657
@ -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)
|
||||
|
@ -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 */
|
||||
|
||||
|
102
gcc/java/parse.y
102
gcc/java/parse.y
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user