OSDN Git Service

2000-07-13 Alexandre Petit-Bianco <apbianco@cygnus.com>
authorapbianco <apbianco@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 21 Jul 2000 00:01:43 +0000 (00:01 +0000)
committerapbianco <apbianco@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 21 Jul 2000 00:01:43 +0000 (00:01 +0000)
* 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)

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@35156 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/java/class.c
gcc/java/java-tree.h
gcc/java/parse.y

index d719f04..f99d0e5 100644 (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)
index 5d132be..07a5521 100644 (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 */
 
index c13eb4b..af7b19b 100644 (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;