Patch: Fix for PR 5057
Tom Tromey
tromey@redhat.com
Wed Nov 14 19:17:00 GMT 2001
This patch fixes PR 5057. It also cleans up the control flow in
maybe_yank_clinit a little bit. At least, I understand it better now,
and I hope you agree.
The problem with the test case in the PR (which I'm checking in btw)
is that analyze_clinit_body will return 1 even when the field being
modified doesn't have an initializer.
This patch also fixes a bug I found where setting a field in a
different class would cause <clinit> to be erroneously yanked. I've
checked in a test case for this as well.
Ok?
Tom
Index: ChangeLog
from Tom Tromey <tromey@redhat.com>
Fixes PR java/5057:
* parse.y (analyze_clinit_body): Added this_class parameter.
Check for more cases where we must keep <clinit>.
(maybe_yank_clinit): Cleaned up flow control.
Index: parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/parse.y,v
retrieving revision 1.334
diff -u -r1.334 parse.y
--- parse.y 2001/12/17 19:14:07 1.334
+++ parse.y 2001/12/18 05:22:04
@@ -141,7 +141,7 @@
static tree java_complete_lhs PARAMS ((tree));
static tree java_complete_tree PARAMS ((tree));
static tree maybe_generate_pre_expand_clinit PARAMS ((tree));
-static int analyze_clinit_body PARAMS ((tree));
+static int analyze_clinit_body PARAMS ((tree, tree));
static int maybe_yank_clinit PARAMS ((tree));
static void start_complete_expand_method PARAMS ((tree));
static void java_complete_expand_method PARAMS ((tree));
@@ -7799,8 +7799,8 @@
MODIFY_EXPR with a constant value. */
static int
-analyze_clinit_body (bbody)
- tree bbody;
+analyze_clinit_body (this_class, bbody)
+ tree this_class, bbody;
{
while (bbody)
switch (TREE_CODE (bbody))
@@ -7814,7 +7814,7 @@
break;
case COMPOUND_EXPR:
- if (analyze_clinit_body (TREE_OPERAND (bbody, 0)))
+ if (analyze_clinit_body (this_class, TREE_OPERAND (bbody, 0)))
return 1;
bbody = TREE_OPERAND (bbody, 1);
break;
@@ -7825,9 +7825,17 @@
if (TREE_CODE (TREE_OPERAND (bbody, 1)) == NEW_ARRAY_INIT
&& flag_emit_class_files)
return 1;
- /* Return 0 if the operand is constant, 1 otherwise. */
- return ! TREE_CONSTANT (TREE_OPERAND (bbody, 1));
+ /* There are a few cases where we're required to keep
+ <clinit>:
+ - If this is an assignment whose operand is not constant,
+ - If this is an assignment to a non-initialized field,
+ - If this field is not a member of the current class.
+ */
+ return (! TREE_CONSTANT (TREE_OPERAND (bbody, 1))
+ || ! DECL_INITIAL (TREE_OPERAND (bbody, 0))
+ || DECL_CONTEXT (TREE_OPERAND (bbody, 0)) != this_class);
+
default:
return 1;
}
@@ -7845,7 +7853,6 @@
{
tree type, current;
tree fbody, bbody;
- int found = 0;
if (!DECL_CLINIT_P (mdecl))
return 0;
@@ -7861,7 +7868,7 @@
return 0;
if (bbody && ! flag_emit_class_files && bbody != empty_stmt_node)
return 0;
-
+
type = DECL_CONTEXT (mdecl);
current = TYPE_FIELDS (type);
@@ -7870,13 +7877,12 @@
{
tree f_init;
- /* We're not interested in non static field */
+ /* We're not interested in non-static fields. */
if (!FIELD_STATIC (current))
continue;
- /* nor in fields with initializers. */
+ /* Nor in fields without initializers. */
f_init = DECL_INITIAL (current);
-
if (f_init == NULL_TREE)
continue;
@@ -7886,20 +7892,15 @@
correctly. */
if (! JSTRING_TYPE_P (TREE_TYPE (current))
&& ! JNUMERIC_TYPE_P (TREE_TYPE (current)))
- break;
+ return 0;
if (! FIELD_FINAL (current) || ! TREE_CONSTANT (f_init))
- break;
+ return 0;
}
/* Now we analyze the method body and look for something that
isn't a MODIFY_EXPR */
- if (bbody == empty_stmt_node)
- found = 0;
- else
- found = analyze_clinit_body (bbody);
-
- if (current || found)
+ if (bbody != empty_stmt_node && analyze_clinit_body (type, bbody))
return 0;
/* Get rid of <clinit> in the class' list of methods */
More information about the Java-patches
mailing list