[gcjx] Patch: FYI: fix static initializer buglet

Tom Tromey tromey@redhat.com
Thu Nov 10 23:41:00 GMT 2005


I'm checking this in on the gcjx branch.

I happened to build the Eclipse CDT C/C++ parser with gcjx today, and
found a little bug.  We were rejecting this code:

    public interface statinit {
      public class inner {
        public static final int x;
        static {
          x = 5;
        }
      }
    }

This is valid -- the 'inner' class is implicitly static and thus can
have a static initializer.  The bug is that we were checking static
initializers too early, before the implicit modifiers were set.

I added a jacks test for this.

Tom

Index: ChangeLog
from  Tom Tromey  <tromey@redhat.com>

	* model/class.cc (check_init_list): Updated comment.
	(add_static_initializer): Don't emit error.
	(create_clinit_method): Check errors.
	(create_finit_method): Check errors.
	(add_instance_initializer): Don't emit error.

Index: model/class.cc
===================================================================
--- model/class.cc	(revision 106607)
+++ model/class.cc	(working copy)
@@ -239,6 +239,9 @@
       else
 	{
 	  // We could optimize away empty statements and blocks here.
+	  // However, if that is done we must take care not to omit
+	  // the error message if there is an empty static initializer
+	  // in an inner class.
 	  return true;
 	}
     }
@@ -308,24 +311,13 @@
 void
 model_class::add_static_initializer (const ref_block &b)
 {
-  if (interface)
-    std::cerr << b->error ("static initializer invalid in interface %1")
-      % this;
-  else if (inner_p ())
-    std::cerr << b->error ("static initializer invalid in inner class %1")
-      % this;
-  else
-    static_inits.push_back (b);
+  static_inits.push_back (b);
 }
 
 void
 model_class::add_instance_initializer (const ref_block &b)
 {
-  if (interface)
-    std::cerr << b->error ("instance initializer invalid in interface %1")
-      % this;
-  else
-    instance_inits.push_back (b);
+  instance_inits.push_back (b);
 }
 
 std::string
@@ -1545,6 +1537,30 @@
   if (static_inits.empty () || ! check_init_list (static_inits))
     return false;
 
+  if (interface || inner_p ())
+    {
+      for (std::list<ref_stmt>::const_iterator i = static_inits.begin ();
+	   i != static_inits.end ();
+	   ++i)
+	{
+	  if (dynamic_cast<model_field_initializer *> ((*i).get ()))
+	    {
+	      // Ok.
+	    }
+	  else if (interface)
+	    std::cerr << (*i)->error ("static initializer invalid "
+				      "in interface %1")
+	      % this;
+	  else
+	    {
+	      assert (inner_p ());
+	      std::cerr << (*i)->error ("static initializer invalid "
+					"in inner class %1")
+		% this;
+	    }
+	}
+    }
+
   location loc = get_location ();
   ref_method clinit = new model_method (loc, this);
   clinit->set_name ("<clinit>");
@@ -1567,6 +1583,19 @@
   if (instance_inits.empty () || ! check_init_list (instance_inits))
     return;
 
+  if (interface)
+    {
+      for (std::list<ref_stmt>::const_iterator i = instance_inits.begin ();
+	   i != instance_inits.end ();
+	   ++i)
+	{
+	  if (! dynamic_cast<model_field_initializer *> ((*i).get ()))
+	    std::cerr << (*i)->error ("instance initializer "
+				      "invalid in interface %1")
+	      % this;
+	}
+    }
+
   location loc = get_location ();
   finit_ = new model_method (loc, this);
   finit_->set_instance_initializer ();



More information about the Java-patches mailing list