[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