This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Patch: gcj interface initialization bug
- From: Tom Tromey <tromey at redhat dot com>
- To: java-patches at gcc dot gnu dot org
- Cc: Gcc Patch List <gcc-patches at gcc dot gnu dot org>
- Date: 09 Mar 2003 23:20:20 -0700
- Subject: Patch: gcj interface initialization bug
- Reply-to: tromey at redhat dot com
This patch fixes a somewhat obscure class initialization bug.
(Though it was discovered in actual application code.)
gcj assumes that all the interfaces of a class are initialized if the
class is initialized. However, this is not the case.
The first part of this patch (in expr.c) fixes this assumption.
The second part adds a bit of code to gcj to force a class
initialization when we're referring to a field in an interface.
New test included; before this patch the test will throw a
NullPointerException.
Tested on x86 Red Hat Linux 7.3, including jacks.
Ok for trunk and 3.3?
Tom
Index: gcc/java/ChangeLog
from Tom Tromey <tromey at redhat dot com>
* parse.y (resolve_field_access): Initialize class if field is
found in another static field.
* expr.c (build_class_init): Don't optimize out initialization of
implemented interface.
Index: gcc/java/expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/expr.c,v
retrieving revision 1.163
diff -u -r1.163 expr.c
--- gcc/java/expr.c 12 Feb 2003 23:39:50 -0000 1.163
+++ gcc/java/expr.c 9 Mar 2003 22:39:06 -0000
@@ -1672,7 +1672,14 @@
build_class_init (tree clas, tree expr)
{
tree init;
- if (inherits_from_p (current_class, clas))
+
+ /* An optimization: if CLAS is a superclass of the class we're
+ compiling, we don't need to initialize it. However, if CLAS is
+ an interface, it won't necessarily be initialized, even if we
+ implement it. */
+ if ((! CLASS_INTERFACE (TYPE_NAME (clas))
+ && inherits_from_p (current_class, clas))
+ || current_class == clas)
return expr;
if (always_initialize_class_p)
Index: gcc/java/parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/parse.y,v
retrieving revision 1.424
diff -u -r1.424 parse.y
--- gcc/java/parse.y 1 Mar 2003 21:46:17 -0000 1.424
+++ gcc/java/parse.y 9 Mar 2003 22:39:11 -0000
@@ -9301,6 +9301,19 @@
return error_mark_node;
if (is_static)
field_ref = maybe_build_class_init_for_field (decl, field_ref);
+
+ /* If we're looking at a static field, we may need to generate a
+ class initialization for it. This can happen when the access
+ looks like `field.ref', where `field' is a static field in an
+ interface we implement. */
+ if (!flag_emit_class_files
+ && !flag_emit_xref
+ && TREE_CODE (where_found) == VAR_DECL
+ && FIELD_STATIC (where_found))
+ {
+ build_static_field_ref (where_found);
+ field_ref = build_class_init (DECL_CONTEXT (where_found), field_ref);
+ }
}
else
field_ref = decl;
Index: libjava/testsuite/ChangeLog
from Tom Tromey <tromey at redhat dot com>
* libjava.lang/initfield.java: New file.
* libjava.lang/initfield.out: New file.
Index: libjava/testsuite/libjava.lang/initfield.java
===================================================================
RCS file: libjava/testsuite/libjava.lang/initfield.java
diff -N libjava/testsuite/libjava.lang/initfield.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libjava/testsuite/libjava.lang/initfield.java 9 Mar 2003 22:39:15 -0000
@@ -0,0 +1,20 @@
+// gcj generated buggy code when we reference a field of a
+// non-constant member that we inherit from an interface.
+
+interface iface
+{
+ final value x = new value();
+}
+
+final class value
+{
+ Object field = "maude";
+}
+
+public class initfield implements iface
+{
+ public static void main(String[] args)
+ {
+ System.out.println(x.field);
+ }
+}
Index: libjava/testsuite/libjava.lang/initfield.out
===================================================================
RCS file: libjava/testsuite/libjava.lang/initfield.out
diff -N libjava/testsuite/libjava.lang/initfield.out
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libjava/testsuite/libjava.lang/initfield.out 9 Mar 2003 22:39:15 -0000
@@ -0,0 +1 @@
+maude