This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
[gcjx] Patch: FYI: array dimensions check
- From: Tom Tromey <tromey at redhat dot com>
- To: Java Patch List <java-patches at gcc dot gnu dot org>
- Date: 25 Jan 2005 19:35:37 -0700
- Subject: [gcjx] Patch: FYI: array dimensions check
- Reply-to: tromey at redhat dot com
I'm checking this in on the gcjx branch.
This checks to make sure that arrays of > 255 dimensions are not used
when compiling to class files. Aside from multianewarray, this
probably doesn't matter much, but it does placate jacks. This
exercise also detected a real bug, for which a fix is forthcoming.
Tom
Index: ChangeLog
from Tom Tromey <tromey@redhat.com>
* bytecode/classwriter.cc (check_type): New method.
(write): Use it.
* bytecode/classwriter.hh (class_writer::check_type): Declare.
* bytecode/generate.cc (visit_for_enhanced): Use check_type.
(visit_cast): Likewise.
(visit_class_ref): Likewise.
(visit_instanceof): Likewise.
(visit_new_array): Likewise.
(visit_array_initializer): Likewise.
Index: bytecode/classwriter.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/bytecode/Attic/classwriter.cc,v
retrieving revision 1.1.2.3
diff -u -r1.1.2.3 classwriter.cc
--- bytecode/classwriter.cc 22 Jan 2005 07:56:24 -0000 1.1.2.3
+++ bytecode/classwriter.cc 26 Jan 2005 02:31:15 -0000
@@ -44,6 +44,17 @@
}
void
+class_writer::check_type (model_element *request, model_type *type)
+{
+ int n_dims = 0;
+ for (; type->array_p (); type = type->element_type ())
+ ++n_dims;
+ if (n_dims > 255)
+ throw request->error ("class file format only allows arrays with "
+ "a maximum of 255 dimensions");
+}
+
+void
class_writer::classify_annotations (const std::list<ref_annotation> &annos,
std::list<model_annotation *> &class_annos,
std::list<model_annotation *> &runtime_annos)
@@ -238,10 +249,15 @@
for (std::list<ref_variable_decl>::const_iterator j = params.begin ();
j != params.end ();
++j)
- len += wide_p ((*j)->type ()) ? 2 : 1;
+ {
+ check_type ((*i).get (), (*j)->type ());
+ len += wide_p ((*j)->type ()) ? 2 : 1;
+ }
if (len > 255)
throw (*i)->error ("method requires more than 255 words of arguments");
+ check_type ((*i).get (), (*i)->get_return_type ());
+
pool->add_utf ((*i)->get_name ());
pool->add_utf ((*i)->get_descriptor ());
if (! (*i)->abstract_p () && ! (*i)->native_p ())
@@ -276,6 +292,8 @@
i != fields.end ();
++i)
{
+ check_type ((*i).get (), (*i)->type ());
+
// We don't bother saving the indices here, we just recompute
// them later. This is ok since the constant pool caches the
// values.
Index: bytecode/classwriter.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/bytecode/Attic/classwriter.hh,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 classwriter.hh
--- bytecode/classwriter.hh 13 Jan 2005 03:18:34 -0000 1.1.2.1
+++ bytecode/classwriter.hh 26 Jan 2005 02:31:15 -0000
@@ -1,6 +1,6 @@
// Write a class file.
-// Copyright (C) 2004 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
@@ -58,6 +58,9 @@
~class_writer ();
void write (directory_cache &);
+
+ // Convenience method for checking number of dimensions of an array.
+ static void check_type (model_element *, model_type *);
};
#endif // GCJX_BYTECODE_CLASSWRITER_HH
Index: bytecode/generate.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/bytecode/Attic/generate.cc,v
retrieving revision 1.1.2.6
diff -u -r1.1.2.6 generate.cc
--- bytecode/generate.cc 20 Jan 2005 18:02:38 -0000 1.1.2.6
+++ bytecode/generate.cc 26 Jan 2005 02:31:16 -0000
@@ -26,6 +26,7 @@
#include "bytecode/attribute.hh"
#include "bytecode/generate.hh"
#include "bytecode/byteutil.hh"
+#include "bytecode/classwriter.hh"
/// Returns how many stack slots the given type takes.
static inline size_t
@@ -651,6 +652,8 @@
}
if (container->type ()->array_p ())
{
+ class_writer::check_type (fstmt, container->type ());
+
bytecode_block *update (new_bytecode_block ());
temporary_local array_var (vars, NULL);
temporary_local arraylen_var (vars, NULL);
@@ -1283,6 +1286,7 @@
++i)
{
int n = vars.request ((*i).get ());
+ class_writer::check_type ((*i).get (), (*i)->type ());
ref_expression init = (*i)->get_initializer ();
if (init)
{
@@ -1371,7 +1375,7 @@
void
-bytecode_generator::visit_array_initializer (model_array_initializer *,
+bytecode_generator::visit_array_initializer (model_array_initializer *initx,
const ref_forwarding_type &elt_type,
const std::list<ref_expression> &exprs)
{
@@ -1379,6 +1383,7 @@
model_type *element_type = elt_type->type ();
model_type *array_type = element_type->array ();
+ class_writer::check_type (initx, array_type);
visit_simple_literal (NULL, jint (exprs.size ()));
emit_new_array (element_type);
@@ -2247,6 +2252,7 @@
}
else
{
+ class_writer::check_type (cast_expr, dest_type);
emit_cast (dest_type, expr->type ());
if (expr_target == IGNORE)
{
@@ -2266,6 +2272,7 @@
|| expr_target == IGNORE);
model_type *type = req->type ();
+ class_writer::check_type (ref, type);
if (type->primitive_p () || type == primitive_void_type)
{
model_class *wrapper = box_primitive_type (type);
@@ -2762,7 +2769,7 @@
}
void
-bytecode_generator::visit_instanceof (model_instanceof *,
+bytecode_generator::visit_instanceof (model_instanceof *inst,
const ref_expression &expr,
const ref_forwarding_type &klass)
{
@@ -2773,6 +2780,7 @@
expr->visit (this);
}
emit (op_instanceof);
+ class_writer::check_type (inst, klass->type ());
int index = cpool->add (klass->type ());
emit2 (index);
@@ -3270,7 +3278,7 @@
}
void
-bytecode_generator::visit_new_array (model_new_array *,
+bytecode_generator::visit_new_array (model_new_array *newarray,
const ref_forwarding_type &elt_type,
const std::list<ref_expression> &indices,
const ref_expression &init)
@@ -3292,6 +3300,7 @@
}
if (len > 1)
{
+ class_writer::check_type (newarray, atype);
emit (op_multianewarray);
int kindex = cpool->add (atype);
emit2 (kindex);