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]
Other format: [Raw text]

Java: Fix for PR java/5935


So basically, this bug occurs when there are anonymous classes declared 
in multiple methods with the same "final" parameters signature, but 
different parameter names (and those parameters are acutally used). What 
happens is that craft_constructor calls build_function_type to generate 
a method_type which includes the implicitly passed "final" arguments to 
its enclosing method, and then fix_method_argument_names to set the 
names of the arguments within the method_type parameter list. However, 
build_function_type is smart, and reuses the same tree_list nodes if it 
finds the function has the same signature as a previous function type. 
Anonymous class constructors are a special case and do not get laid 
out/implemented until after everything else has been expanded, so 
fix_method_argument_names ends up changing the parameter names on 
method_type tree_list nodes which are shared with other anonymous 
constructor decls. When the body of each anonymous constructor is 
eventually generated, the wrong parameter name is used and if that 
parameter is actually referenced within the anonymous class body, we get 
an error. Yucky.

The solution is simply to call fix_constructors (should really be called 
"implement_constructor_body", except that it does something else as 
well) right after craft_constructor. This ensures that another anonymous 
class declaration doesnt get the chance to clobber over the existing 
parameter names.

Rebuilt libjava and ran test suite with no regressions on 3.1 branch, 
PowerPC linux. Java on mainline seems to have regressions but they aint 
caused by this patch. OK to commit?

regards

Bryce.


2002-03-14  Bryce McKinlay  <bryce@waitaki.otago.ac.nz>

	* parse.y (craft_constructor): Return the constructor decl.
	(java_expand_classes): Update comments.
	(lookup_method_invoke): Call fix_constructors immediately for
	anonymous class. Fixes PR java/5935.

Index: parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/parse.y,v
retrieving revision 1.359
diff -u -r1.359 parse.y
--- parse.y	2002/03/12 18:01:23	1.359
+++ parse.y	2002/03/14 03:58:02
@@ -243,7 +243,7 @@
 static void fix_constructors PARAMS ((tree));
 static tree build_alias_initializer_parameter_list PARAMS ((int, tree,
 							    tree, int *));
-static void craft_constructor PARAMS ((tree, tree));
+static tree craft_constructor PARAMS ((tree, tree));
 static int verify_constructor_super PARAMS ((tree));
 static tree create_artificial_method PARAMS ((tree, int, tree, tree, tree));
 static void start_artificial_method_body PARAMS ((tree));
@@ -5400,7 +5400,7 @@
    where found. ARGS is non NULL when a special signature must be
    enforced. This is the case for anonymous classes.  */
 
-static void
+static tree
 craft_constructor (class_decl, args)
      tree class_decl, args;
 {
@@ -5449,6 +5449,7 @@
   /* Now, mark the artificial parameters. */
   DECL_FUNCTION_NAP (decl) = artificial;
   DECL_FUNCTION_SYNTHETIC_CTOR (decl) = DECL_CONSTRUCTOR_P (decl) = 1;
+  return decl;
 }
 
 
@@ -8999,8 +9000,10 @@
     }
   input_filename = main_input_filename;
 
-  /* Find anonymous classes and expand their constructor, now they
-     have been fixed. */
+
+  /* Find anonymous classes and expand their constructor. This extra pass is
+     neccessary because the constructor itself is only generated when the
+     method in which it is defined is expanded. */
   for (cur_ctxp = ctxp_for_generation; cur_ctxp; cur_ctxp = cur_ctxp->next)
     {
       tree current;
@@ -9018,7 +9021,7 @@
 		      restore_line_number_status (1);
 		      java_complete_expand_method (d);
 		      restore_line_number_status (0);
-		      break;	/* We now there are no other ones */
+		      break;	/* There is only one constructor. */
 		    }
 		}
 	    }
@@ -10855,7 +10858,14 @@
      know the arguments' types. */
 
   if (lc && ANONYMOUS_CLASS_P (class))
-    craft_constructor (TYPE_NAME (class), atl);
+    {
+      tree saved_current_class;
+      tree mdecl = craft_constructor (TYPE_NAME (class), atl);
+      saved_current_class = current_class;
+      current_class = class;
+      fix_constructors (mdecl);
+      current_class = saved_current_class;
+    }
 
   /* Find all candidates and then refine the list, searching for the
      most specific method. */

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