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]

Patch: gcj interface initialization bug


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


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