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]

[gcjx] Patch: FYI: array dimensions check


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);


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