This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
[gcjx] Patch: FYI: a few crash fixes
- From: Tom Tromey <tromey at redhat dot com>
- To: Java Patch List <java-patches at gcc dot gnu dot org>
- Date: 08 Mar 2005 15:59:03 -0700
- Subject: [gcjx] Patch: FYI: a few crash fixes
- Reply-to: tromey at redhat dot com
I'm checking this in on the gcjx branch.
This is a miscellaneous patch of a few crash fixes:
- set DECL_CONTEXT when needed (this code actually goes away as I recall)
- don't try to generate code for an abstract method
- handle 'if' without an 'else'
- special-case 'final' methods declared in Object -- these don't go
in the vtable
- don't add fields to a class that already has fields (special case
for Object and Class)
Tom
Index: ChangeLog
from Tom Tromey <tromey@redhat.com>
* tree.cc (wrap_synchronized): Set DECL_CONTEXT on new variable.
* treegen.cc (generate): Skip abstract methods.
* tree.cc (visit_if): Handle case where there is no 'else'
statement.
* abi.cc (get_vtable_index): Handle final methods from Object.
* builtins.cc (lay_out_class): Skip types that already have
fields.
Index: abi.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/abi.cc,v
retrieving revision 1.1.2.12
diff -u -r1.1.2.12 abi.cc
--- abi.cc 8 Mar 2005 18:59:54 -0000 1.1.2.12
+++ abi.cc 8 Mar 2005 21:43:16 -0000
@@ -213,6 +213,11 @@
assert (method->get_declaring_class () == klass->get ());
if (method->static_p () || method->constructor_p ())
return integer_minus_one_node;
+ // A special case for methods that are never virtual.
+ if (method->final_p ()
+ && (method->get_declaring_class ()
+ == global->get_compiler ()->java_lang_Object ()))
+ return integer_minus_one_node;
return build_int_cst (type_jint, klass->find_in_vtable (method));
}
Index: builtins.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/builtins.cc,v
retrieving revision 1.1.2.19
diff -u -r1.1.2.19 builtins.cc
--- builtins.cc 8 Mar 2005 21:41:42 -0000 1.1.2.19
+++ builtins.cc 8 Mar 2005 21:43:16 -0000
@@ -567,45 +567,52 @@
// Fix the ordering.
TYPE_METHODS (klass_record) = nreverse (TYPE_METHODS (klass_record));
- // Ensure all non-static fields have been added.
- std::list<ref_field> fields = klass->get_fields ();
- for (std::list<ref_field>::const_iterator i = fields.begin ();
- i != fields.end ();
- ++i)
- add (klass_record, (*i).get ());
-
- // For arrays, add a "data" member. This field isn't visible to
- // java, but is needed for code generation.
- if (klass->array_p ())
+ // FIXME: This is sort of bogus, because we could easily create
+ // Class and Object here. Meanwhile, these two classes have their
+ // fields added elsewhere. Skipping any class that already has
+ // fields should suffice.
+ if (TYPE_FIELDS (klass_record) == NULL_TREE)
{
- tree elt_type = map_type (klass->element_type ());
- tree data = build_decl (FIELD_DECL, get_identifier ("data"),
- build_array_type (elt_type,
- build_index_type (integer_zero_node)));
- DECL_CONTEXT (data) = klass_record;
- TREE_PUBLIC (data) = 1;
- DECL_ARTIFICIAL (data) = 1;
-
- TREE_CHAIN (data) = TYPE_FIELDS (klass_record);
- TYPE_FIELDS (klass_record) = data;
-
- // Also update the "length" field.
- tree length_field = find_decl (klass_record, "length");
- TREE_READONLY (length_field) = 1;
- }
+ // Ensure all non-static fields have been added.
+ std::list<ref_field> fields = klass->get_fields ();
+ for (std::list<ref_field>::const_iterator i = fields.begin ();
+ i != fields.end ();
+ ++i)
+ add (klass_record, (*i).get ());
+
+ // For arrays, add a "data" member. This field isn't visible to
+ // java, but is needed for code generation.
+ if (klass->array_p ())
+ {
+ tree elt_type = map_type (klass->element_type ());
+ tree data = build_decl (FIELD_DECL, get_identifier ("data"),
+ build_array_type (elt_type,
+ build_index_type (integer_zero_node)));
+ DECL_CONTEXT (data) = klass_record;
+ TREE_PUBLIC (data) = 1;
+ DECL_ARTIFICIAL (data) = 1;
+
+ TREE_CHAIN (data) = TYPE_FIELDS (klass_record);
+ TYPE_FIELDS (klass_record) = data;
+
+ // Also update the "length" field.
+ tree length_field = find_decl (klass_record, "length");
+ TREE_READONLY (length_field) = 1;
+ }
- // Fix the ordering.
- TYPE_FIELDS (klass_record) = nreverse (TYPE_FIELDS (klass_record));
+ // Fix the ordering.
+ TYPE_FIELDS (klass_record) = nreverse (TYPE_FIELDS (klass_record));
- // Link to the superclass.
- if (super_record != NULL_TREE)
- {
- tree base = build_decl (FIELD_DECL, NULL_TREE, super_record);
- DECL_IGNORED_P (base) = 1;
- TREE_CHAIN (base) = TYPE_FIELDS (klass_record);
- TYPE_FIELDS (klass_record) = base;
- DECL_SIZE (base) = TYPE_SIZE (super_record);
- DECL_SIZE_UNIT (base) = TYPE_SIZE_UNIT (super_record);
+ // Link to the superclass.
+ if (super_record != NULL_TREE)
+ {
+ tree base = build_decl (FIELD_DECL, NULL_TREE, super_record);
+ DECL_IGNORED_P (base) = 1;
+ TREE_CHAIN (base) = TYPE_FIELDS (klass_record);
+ TYPE_FIELDS (klass_record) = base;
+ DECL_SIZE (base) = TYPE_SIZE (super_record);
+ DECL_SIZE_UNIT (base) = TYPE_SIZE_UNIT (super_record);
+ }
}
lay_out_vtable (klass);
Index: tree.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/tree.cc,v
retrieving revision 1.1.2.13
diff -u -r1.1.2.13 tree.cc
--- tree.cc 8 Mar 2005 04:04:20 -0000 1.1.2.13
+++ tree.cc 8 Mar 2005 21:43:17 -0000
@@ -132,6 +132,7 @@
{
tree k;
if (meth->static_p ())
+ // FIXME: this is kind of wrong for new ABI code.
k = build_class_ref (meth->get_declaring_class ());
else
k = this_tree;
@@ -623,8 +624,14 @@
tree cond_tree = current;
true_branch->visit (this);
tree true_tree = current;
- false_branch->visit (this);
- tree false_tree = current;
+ tree false_tree;
+ if (false_branch)
+ {
+ false_branch->visit (this);
+ false_tree = current;
+ }
+ else
+ false_tree = build_empty_stmt ();
current = build3 (COND_EXPR, void_type_node, cond_tree,
true_tree, false_tree);
@@ -750,6 +757,7 @@
tree expr_decl = build_decl (VAR_DECL, get_identifier (buf),
TREE_TYPE (expr));
DECL_INITIAL (expr_decl) = current;
+ DECL_CONTEXT (expr_decl) = method_tree;
TREE_CHAIN (expr_decl) = BLOCK_VARS (current_block);
BLOCK_VARS (current_block) = expr_decl;
@@ -1053,6 +1061,7 @@
const ref_expression &lhs,
const ref_expression &rhs)
{
+ // FIXME: String '+'.
binary_operator (PLUS_EXPR, lhs, rhs);
}
Index: treegen.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/treegen.cc,v
retrieving revision 1.1.2.7
diff -u -r1.1.2.7 treegen.cc
--- treegen.cc 8 Mar 2005 00:45:41 -0000 1.1.2.7
+++ treegen.cc 8 Mar 2005 21:43:17 -0000
@@ -56,6 +56,13 @@
i != methods.end ();
++i)
{
+ // No need to do anything for abstract methods.
+ // FIXME: Or... set line number??
+ // We could generate stubs that throw an exception with
+ // nice information...
+ if (((*i)->get_modifiers () & ACC_ABSTRACT) != 0)
+ continue;
+
tree_generator gen (builtins, wrapper);
tree method = gen.generate ((*i).get ());