This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

JAVA: Fix clone() on arrays


This patch fixes a recent regression with calling clone() on array
instances:

 http://gcc.gnu.org/ml/java/2001-02/msg00262.html

Although clone() is a protected method in object, array classes
implicitly "override" it with a public method that throws no checked
exceptions (10.7). This is actually implemented as a special case by
java compilers and runtimes, as a call to Object.clone() that is not
subject to the ordinary access and exception checks:

public class A2
{
  void a()
 {
    int[] copy = (int[]) new int[1].clone();
  }
}

$ jcf-dump A2.class
[...]
Constant pool (count: 20):
#2: Methodref class: 5=java.lang.Object name_and_type: 14=<clone
()java.lang.Object>
[...]

Now we're down to (on branch):

                === libjava Summary ===

# of expected passes            1597
# of unexpected failures        2
# of unexpected successes       17
# of expected failures          108

ok to commit?

regards

  [ bryce ]


2001-02-18  Bryce McKinlay  <bryce@albatross.co.nz>

	* typeck.c (build_java_array_type): Don't try to poke a public `clone'
	method into array types.
	* parse.y (patch_method_invocation): Bypass access check on clone call
	to array instance.

Index: parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/parse.y,v
retrieving revision 1.251.2.3
diff -u -r1.251.2.3 parse.y
--- parse.y	2001/02/15 01:23:23	1.251.2.3
+++ parse.y	2001/02/18 08:28:30
@@ -9684,6 +9684,7 @@
   int is_static_flag = 0;
   int is_super_init = 0;
   tree this_arg = NULL_TREE;
+  int is_array_clone_call = 0;
   
   /* Should be overriden if everything goes well. Otherwise, if
      something fails, it should keep this value. It stop the
@@ -9758,6 +9759,9 @@
       else
 	this_arg = primary = resolved;
       
+      if (TYPE_ARRAY_P (type) && identifier == get_identifier ("clone"))
+        is_array_clone_call = 1;
+      
       /* IDENTIFIER_WFL will be used to report any problem further */
       wfl = identifier_wfl;
     }
@@ -9839,6 +9843,10 @@
          can't be executed then. */
       if (!list)
 	PATCH_METHOD_RETURN_ERROR ();
+      
+      if (TYPE_ARRAY_P (class_to_search)
+          && DECL_NAME (list) == get_identifier ("clone"))
+        is_array_clone_call = 1;
 
       /* Check for static reference if non static methods */
       if (check_for_static_method_reference (wfl, patch, list, 
@@ -9909,7 +9917,9 @@
      return the call */
   if (not_accessible_p (DECL_CONTEXT (current_function_decl), list,
 			(primary ? TREE_TYPE (TREE_TYPE (primary)) : 
-			 NULL_TREE), from_super))
+			 NULL_TREE), from_super)
+      /* Calls to clone() on array types are permitted as a special-case. */
+      && !is_array_clone_call)
     {
       char *fct_name = (char *) IDENTIFIER_POINTER (DECL_NAME (list));
       char *access = java_accstring_lookup (get_access_flags_from_decl (list));
Index: typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/typeck.c,v
retrieving revision 1.37.2.1
diff -u -r1.37.2.1 typeck.c
--- typeck.c	2001/02/15 01:23:23	1.37.2.1
+++ typeck.c	2001/02/18 08:28:30
@@ -424,11 +424,6 @@
   FIELD_FINAL (fld) = 1;
   TREE_READONLY (fld) = 1;
 
-  /* Add clone method.  This is different from Object.clone because it
-     is public.  */
-  add_method (t, ACC_PUBLIC | ACC_FINAL, get_identifier ("clone"),
-             get_identifier ("()Ljava/lang/Object;"));
-
   atype = build_prim_array_type (element_type, length);
   arfld = build_decl (FIELD_DECL, get_identifier ("data"), atype);
   DECL_CONTEXT (arfld) = t;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]