From: Alexandre Petit-Bianco Date: Fri, 23 Mar 2001 19:42:25 +0000 (-0800) Subject: re PR java/1213 (gcj should check for incorrect CLASSPATH) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b124f72e29e5b0ff7b6cbd85fab0e9d4676d7b9f;p=gcc.git re PR java/1213 (gcj should check for incorrect CLASSPATH) 2001-03-22 Alexandre Petit-Bianco * 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 --- diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 18d3b5c71e8..bb52739c99a 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,23 @@ +2001-03-23 Alexandre Petit-Bianco + + * 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 * gcj.texi (Configure-time Options): Add -fcheck-references. diff --git a/gcc/java/gcj.texi b/gcc/java/gcj.texi index c31a92339a1..bb94dff3c8a 100644 --- a/gcc/java/gcj.texi +++ b/gcc/java/gcj.texi @@ -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 diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h index 6e3c979d23e..afd892e53e2 100644 --- a/gcc/java/java-tree.h +++ b/gcc/java/java-tree.h @@ -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. */ diff --git a/gcc/java/jcf-parse.c b/gcc/java/jcf-parse.c index 0b3a4b553b9..f235f6d3f04 100644 --- a/gcc/java/jcf-parse.c +++ b/gcc/java/jcf-parse.c @@ -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 ); diff --git a/gcc/java/jcf-reader.c b/gcc/java/jcf-reader.c index f34bddb6e75..5df7a2e6353 100644 --- a/gcc/java/jcf-reader.c +++ b/gcc/java/jcf-reader.c @@ -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++) { diff --git a/gcc/java/jcf-write.c b/gcc/java/jcf-write.c index f819d835ad5..46f73fe9cbb 100644 --- a/gcc/java/jcf-write.c +++ b/gcc/java/jcf-write.c @@ -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; diff --git a/gcc/java/jcf.h b/gcc/java/jcf.h index 6fb6c254dde..4203ec0853d 100644 --- a/gcc/java/jcf.h +++ b/gcc/java/jcf.h @@ -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; diff --git a/gcc/java/lang-options.h b/gcc/java/lang-options.h index 776b432a712..f65bb459bee 100644 --- a/gcc/java/lang-options.h +++ b/gcc/java/lang-options.h @@ -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" }, diff --git a/gcc/java/lang.c b/gcc/java/lang.c index 38aedc74d28..8f9f5b21773 100644 --- a/gcc/java/lang.c +++ b/gcc/java/lang.c @@ -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