aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAlexandre Petit-Bianco <apbianco@gcc.gnu.org>2000-07-20 17:01:43 -0700
committerAlexandre Petit-Bianco <apbianco@gcc.gnu.org>2000-07-20 17:01:43 -0700
commit4dbf4496573255460757de76bb8347669196587c (patch)
treef3e7044d39e99e82b097d95cb4c440ce2d639c9f /gcc
parentc59ff527c551ccc7cf500e3095d2b7b111d6c907 (diff)
downloadgcc-4dbf4496573255460757de76bb8347669196587c.zip
gcc-4dbf4496573255460757de76bb8347669196587c.tar.gz
gcc-4dbf4496573255460757de76bb8347669196587c.tar.bz2
[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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/java/class.c7
-rw-r--r--gcc/java/java-tree.h3
-rw-r--r--gcc/java/parse.y102
3 files changed, 88 insertions, 24 deletions
diff --git a/gcc/java/class.c b/gcc/java/class.c
index d719f04..f99d0e5 100644
--- a/gcc/java/class.c
+++ b/gcc/java/class.c
@@ -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)
diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h
index 5d132be..07a5521 100644
--- a/gcc/java/java-tree.h
+++ b/gcc/java/java-tree.h
@@ -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 */
diff --git a/gcc/java/parse.y b/gcc/java/parse.y
index c13eb4b..af7b19b 100644
--- a/gcc/java/parse.y
+++ b/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;