]> gcc.gnu.org Git - gcc.git/commitdiff
re PR java/1213 (gcj should check for incorrect CLASSPATH)
authorAlexandre Petit-Bianco <apbianco@redhat.com>
Fri, 23 Mar 2001 19:42:25 +0000 (11:42 -0800)
committerAlexandre Petit-Bianco <apbianco@gcc.gnu.org>
Fri, 23 Mar 2001 19:42:25 +0000 (11:42 -0800)
2001-03-22  Alexandre Petit-Bianco  <apbianco@redhat.com>

* gcj.texi (Input Options): documented the check for attribute
`gnu.gcc.gccj-compiled' and the `-fforce-classes-archive-check' flag.
* java-tree.h (flag_force_classes_archive_check): Declared extern.
* jcf-parse.c (HANDLE_GCJCOMPILED_ATTRIBUTE): New macro.
(jcf_parse): Check for the right classes archive if necessary.
* jcf-reader.c (get_attribute): Define `MATCH_ATTRIBUTE' and use it.
(jcf_parse_fields): Fixed indentation.
* jcf-write.c (append_gcj_attribute): New function.
(generate_classfile): Compute the attribute count, invoke
`append_gcj_attribute'.
* jcf.h (typedef struct JCF): `seen_in_zip' and `java_source'
turned into bit fields. New bit field `right_zip.'
(JCF_ZERO): Set `right_zip' to zero.
* lang-options.h (-fforce-classes-archive-check): Added flag.
* lang.c (flag_force_classes_archive_check): New flag.
(lang_f_options): New entry `force-classes-archive-check.'
Fixes PR java/1213.

(http://gcc.gnu.org/ml/gcc-patches/2001-03/msg01662.html)

From-SVN: r40788

gcc/java/ChangeLog
gcc/java/gcj.texi
gcc/java/java-tree.h
gcc/java/jcf-parse.c
gcc/java/jcf-reader.c
gcc/java/jcf-write.c
gcc/java/jcf.h
gcc/java/lang-options.h
gcc/java/lang.c

index 18d3b5c71e82c3d535c51b6d4fa89c4337eb9ede..bb52739c99ae1c844d749e1eaefde79df411a98d 100644 (file)
@@ -1,3 +1,23 @@
+2001-03-23  Alexandre Petit-Bianco  <apbianco@redhat.com>
+
+       * gcj.texi (Input Options): documented the check for attribute
+       `gnu.gcc.gccj-compiled' and the `-fforce-classes-archive-check' flag.
+       * java-tree.h (flag_force_classes_archive_check): Declared extern.
+       * jcf-parse.c (HANDLE_GCJCOMPILED_ATTRIBUTE): New macro.
+       (jcf_parse): Check for the right classes archive if necessary.
+       * jcf-reader.c (get_attribute): Define `MATCH_ATTRIBUTE' and use it.
+       (jcf_parse_fields): Fixed indentation.
+       * jcf-write.c (append_gcj_attribute): New function.
+       (generate_classfile): Compute the attribute count, invoke
+       `append_gcj_attribute'.
+       * jcf.h (typedef struct JCF): `seen_in_zip' and `java_source'
+       turned into bit fields. New bit field `right_zip.'
+       (JCF_ZERO): Set `right_zip' to zero.
+       * lang-options.h (-fforce-classes-archive-check): Added flag.
+       * lang.c (flag_force_classes_archive_check): New flag.
+       (lang_f_options): New entry `force-classes-archive-check.'
+       Fixes PR java/1213.
+
 2001-02-07  Andrew Haley  <aph@redhat.com>
 
        * gcj.texi (Configure-time Options): Add -fcheck-references.
index c31a92339a1c9f7afaed35116c245a1866ef1c75..bb94dff3c8afde26d28946b367021f6196679647 100644 (file)
@@ -624,6 +624,20 @@ suppressed by @code{--CLASSPATH}), then its value is appended.
 Finally, the built-in system directory, @file{libgcj.jar}, is appended.
 @end itemize
 
+The classfile built by @code{gcj} for the class @code{java.lang.Object}
+(and placed in @code{libgcj.jar}) contains a special zero length
+attribute @code{gnu.gcj.gcj-compiled}. The compiler looks for this
+attribute when loading @code{java.lang.Object} and will report an error
+if it isn't found, unless it compiles to bytecode (the option
+@code{-fforce-classes-archive-check} can be used to overide this
+behavior in this particular case.)
+
+@table @code
+@item -fforce-classes-archive-check
+This forces the compiler to always check for the special zero length
+attribute @code{gnu.gcj.gcj-compiled} in @code{java.lang.Object} and
+issue an error if it isn't found.
+@end table
 
 @node Encodings
 @section Encodings
index 6e3c979d23e3d4ad3dcb8911c1d27448e1e61576..afd892e53e2ab0e3bce77de5bb127bd9025b4dd0 100644 (file)
@@ -153,6 +153,10 @@ extern int flag_jni;
 
 extern int flag_extraneous_semicolon;
 
+/* When non zero, always check for a non gcj generated classes archive.  */
+
+extern int flag_force_classes_archive_check;
+
 /* When non zero, we emit xref strings. Values of the flag for xref
    backends are defined in xref.h.  */
 
index 0b3a4b553b9c292407b98830019088022210b259..f235f6d3f041fa8105ae468547aeb42701445f71 100644 (file)
@@ -236,6 +236,12 @@ set_source_filename (jcf, index)
     DECL_ARTIFICIAL (current_method) = 1;                              \
 }
 
+#define HANDLE_GCJCOMPILED_ATTRIBUTE()         \
+{                                              \
+  if (current_class == object_type_node)       \
+    jcf->right_zip = 1;                                \
+}
+
 #include "jcf-reader.c"
 
 static int yydebug;
@@ -710,7 +716,15 @@ jcf_parse (jcf)
 
   layout_class (current_class);
   if (current_class == object_type_node)
-    layout_class_methods (object_type_node);
+    {
+      layout_class_methods (object_type_node);
+      /* If we don't have the right archive, emit a verbose warning.
+        If we're generating bytecode, emit the warning only if
+        -fforce-classes-archive-check was specified. */
+      if (!jcf->right_zip
+         && (!flag_emit_class_files || flag_force_classes_archive_check))
+       fatal_error ("The `java.lang.Object' that was found in `%s' didn't have the special zero-length `gnu.gcj.gcj-compiled' attribute. This generally means that your classpath is incorrect set. Use `info gcj \"Input Options\"' to see the info page describing how to set the classpath.", jcf->filename);
+    }
   else
     all_class_list = tree_cons (NULL_TREE,
                                TYPE_NAME (current_class), all_class_list );
index f34bddb6e755c5f2a7331a3bb8b64815c31dbd74..5df7a2e6353e3eebbf60887383492a5bacf8005e 100644 (file)
@@ -120,6 +120,9 @@ DEFUN(get_attribute, (jcf),
   name_length = JPOOL_UTF_LENGTH (jcf, attribute_name);
   name_data = JPOOL_UTF_DATA (jcf, attribute_name);
 
+#define MATCH_ATTRIBUTE(S) \
+  (name_length == sizeof (S)-1 && memcmp (name_data, S, sizeof (S)-1) == 0)
+
 #ifdef IGNORE_ATTRIBUTE
    if (IGNORE_ATTRIBUTE (jcf, attribute_name, attribute_length))
      {
@@ -128,7 +131,7 @@ DEFUN(get_attribute, (jcf),
    else
 #endif
 #ifdef HANDLE_SOURCEFILE
-  if (name_length == 10 && memcmp (name_data, "SourceFile", 10) == 0)
+  if (MATCH_ATTRIBUTE ("SourceFile"))
     {
       uint16 sourcefile_index = JCF_readu2 (jcf);
       HANDLE_SOURCEFILE(sourcefile_index);
@@ -136,7 +139,7 @@ DEFUN(get_attribute, (jcf),
   else
 #endif
 #ifdef HANDLE_CONSTANTVALUE
-  if (name_length == 13 && memcmp (name_data, "ConstantValue", 13) == 0)
+  if (MATCH_ATTRIBUTE ("ConstantValue"))
     {
       uint16 constantvalue_index = JCF_readu2 (jcf);
       if (constantvalue_index <= 0 || constantvalue_index >= JPOOL_SIZE(jcf))
@@ -146,7 +149,7 @@ DEFUN(get_attribute, (jcf),
   else
 #endif
 #ifdef HANDLE_CODE_ATTRIBUTE
-  if (name_length == 4 && memcmp (name_data, "Code", 4) == 0)
+  if (MATCH_ATTRIBUTE ("Code"))
     {
       uint16 j;
       uint16 max_stack ATTRIBUTE_UNUSED = JCF_readu2 (jcf);
@@ -175,7 +178,7 @@ DEFUN(get_attribute, (jcf),
   else
 #endif /* HANDLE_CODE_ATTRIBUTE */
 #ifdef HANDLE_EXCEPTIONS_ATTRIBUTE
-  if (name_length == 10 && memcmp (name_data, "Exceptions", 10) == 0)
+  if (MATCH_ATTRIBUTE ("Exceptions"))
     {
       uint16 count = JCF_readu2 (jcf);
       HANDLE_EXCEPTIONS_ATTRIBUTE (count);
@@ -183,7 +186,7 @@ DEFUN(get_attribute, (jcf),
   else
 #endif
 #ifdef HANDLE_LINENUMBERTABLE_ATTRIBUTE
-  if (name_length == 15 && memcmp (name_data, "LineNumberTable", 15) == 0)
+  if (MATCH_ATTRIBUTE ("LineNumberTable"))
     {
       uint16 count = JCF_readu2 (jcf);
       HANDLE_LINENUMBERTABLE_ATTRIBUTE (count);
@@ -191,7 +194,7 @@ DEFUN(get_attribute, (jcf),
   else
 #endif
 #ifdef HANDLE_LOCALVARIABLETABLE_ATTRIBUTE
-  if (name_length == 18 && memcmp (name_data, "LocalVariableTable", 18) == 0)
+  if (MATCH_ATTRIBUTE ("LocalVariableTable"))
     {
       uint16 count = JCF_readu2 (jcf);
       HANDLE_LOCALVARIABLETABLE_ATTRIBUTE (count);
@@ -199,7 +202,7 @@ DEFUN(get_attribute, (jcf),
   else
 #endif
 #ifdef HANDLE_INNERCLASSES_ATTRIBUTE
-  if (name_length == 12 && memcmp (name_data, "InnerClasses", 12) == 0)
+  if (MATCH_ATTRIBUTE ("InnerClasses"))
     {
       uint16 count = JCF_readu2 (jcf);
       HANDLE_INNERCLASSES_ATTRIBUTE (count);
@@ -207,11 +210,18 @@ DEFUN(get_attribute, (jcf),
   else
 #endif
 #ifdef HANDLE_SYNTHETIC_ATTRIBUTE
-  if (name_length == 9 && memcmp (name_data, "Synthetic", 9) == 0)
+  if (MATCH_ATTRIBUTE ("Synthetic"))
     {
       HANDLE_SYNTHETIC_ATTRIBUTE ();
     }
   else
+#endif
+#ifdef HANDLE_GCJCOMPILED_ATTRIBUTE
+  if (MATCH_ATTRIBUTE ("gnu.gcj.gcj-compiled"))
+    {
+      HANDLE_GCJCOMPILED_ATTRIBUTE ();
+    }
+  else
 #endif
     {
 #ifdef PROCESS_OTHER_ATTRIBUTE
@@ -362,7 +372,7 @@ DEFUN(jcf_parse_fields, (jcf),
       uint16 attribute_count = JCF_readu2 (jcf);
 #ifdef HANDLE_START_FIELD
       HANDLE_START_FIELD (access_flags, name_index, signature_index,
-                   attribute_count);
+                         attribute_count);
 #endif
       for (j = 0; j < attribute_count; j++)
        {
index f819d835ad530e646ad9773b9cf5bbaf2da5b371..46f73fe9cbb3708a37a4971da6e3597462c916ea 100644 (file)
@@ -346,10 +346,11 @@ static char *make_class_file_name PARAMS ((tree));
 static unsigned char *append_synthetic_attribute PARAMS ((struct jcf_partial *));
 static void append_innerclasses_attribute PARAMS ((struct jcf_partial *, tree));
 static void append_innerclasses_attribute_entry PARAMS ((struct jcf_partial *, tree, tree));
+static void append_gcj_attribute PARAMS ((struct jcf_partial *, tree));
 
 /* Utility macros for appending (big-endian) data to a buffer.
    We assume a local variable 'ptr' points into where we want to
-   write next, and we assume enoygh space has been allocated. */
+   write next, and we assume enough space has been allocated. */
 
 #ifdef ENABLE_JC1_CHECKING
 static int CHECK_PUT PARAMS ((void *, struct jcf_partial *, int));
@@ -3110,8 +3111,11 @@ generate_classfile (clas, state)
     }
   ptr = append_chunk (NULL, 10, state);
 
-  i = ((INNER_CLASS_TYPE_P (clas) 
-       || DECL_INNER_CLASS_LIST (TYPE_NAME (clas))) ? 2 : 1);
+  i = 1;               /* Source file always exists as an attribute */
+  if (INNER_CLASS_TYPE_P (clas) || DECL_INNER_CLASS_LIST (TYPE_NAME (clas)))
+    i++;
+  if (clas == object_type_node)
+    i++;
   PUT2 (i);                    /* attributes_count */
 
   /* generate the SourceFile attribute. */
@@ -3126,6 +3130,7 @@ generate_classfile (clas, state)
   PUT4 (2);
   i = find_utf8_constant (&state->cpool, get_identifier (source_file));
   PUT2 (i);
+  append_gcj_attribute (state, clas);
   append_innerclasses_attribute (state, clas);
 
   /* New finally generate the contents of the constant pool chunk. */
@@ -3157,6 +3162,24 @@ append_synthetic_attribute (state)
   return ptr;
 }
 
+static void
+append_gcj_attribute (state, class)
+     struct jcf_partial *state;
+     tree class;
+{
+  unsigned char *ptr;
+  int i;
+
+  if (class != object_type_node)
+    return;
+
+  ptr = append_chunk (NULL, 6, state); /* 2+4 */
+  i = find_utf8_constant (&state->cpool, 
+                         get_identifier ("gnu.gcj.gcj-compiled"));
+  PUT2 (i);                    /* Attribute string index */
+  PUT4 (0);                    /* Attribute length */
+}
+
 static void
 append_innerclasses_attribute (state, class)
      struct jcf_partial *state;
index 6fb6c254dde9e7e0d8b58adb1fbe18f80181c8cc..4203ec0853d67bbd9a65165f6c221f1994dd8253 100644 (file)
@@ -88,7 +88,8 @@ typedef struct JCF {
   unsigned char *buffer_end;
   unsigned char *read_ptr;
   unsigned char *read_end;
-  int java_source;
+  int java_source : 1;
+  int right_zip : 1;
   jcf_filbuf_t filbuf;
   void *read_state;
   const char *filename;
index 776b432a712cae726c6edc504e9c1ce0763f9835..f65bb459beeeabc69def0109b50b7965b65e400a 100644 (file)
@@ -49,3 +49,5 @@ DEFINE_LANG_NAME ("Java")
     "Warn if modifiers are specified when not necessary"},
   { "-Wextraneous-semicolon", "Warn if deprecated empty statements are found"},
   { "-Wout-of-date", "Warn if .class files are out of date" },
+  { "-fforce-classes-archive-check", 
+    "Always check for non gcj generated classes archives" },
index 38aedc74d28ed7c6d9c1fe4bc59b7b833ee0158e..8f9f5b21773499cacc585fe11283cd463d334c8a 100644 (file)
@@ -147,6 +147,9 @@ const char *current_encoding = NULL;
 /* When non zero, report the now deprecated empty statements.  */
 int flag_extraneous_semicolon;
 
+/* When non zero, always check for a non gcj generated classes archive.  */
+int flag_force_classes_archive_check;
+
 /* From gcc/flags.h, and indicates if exceptions are turned on or not.  */
 
 extern int flag_new_exceptions;
@@ -169,6 +172,7 @@ lang_f_options[] =
   {"hash-synchronization", &flag_hash_synchronization, 1},
   {"jni", &flag_jni, 1},
   {"check-references", &flag_check_references, 1},
+  {"force-classes-archive-check", &flag_force_classes_archive_check, 1}
 };
 
 static struct string_option
This page took 0.097007 seconds and 5 git commands to generate.