This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Java: Fix for PR java/5935
- From: Bryce McKinlay <bryce at waitaki dot otago dot ac dot nz>
- To: java-patches at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org, R dot Hautz at inn-salzach dot de
- Date: Fri, 15 Mar 2002 00:42:45 +1300
- Subject: 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. */