This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Java: fix to java/1213
- To: gcc-patches at gcc dot gnu dot org, java-patches at gcc dot gnu dot org
- Subject: [PATCH] Java: fix to java/1213
- From: Alexandre Petit-Bianco <apbianco at cygnus dot com>
- Date: Thu, 22 Mar 2001 18:04:48 -0800
- Reply-to: apbianco at cygnus dot com
This fixes java/1213. Since it improves the user experience by
reporting whether the main archive was generated by gcj or not
(http://gcc.gnu.org/java/faq.html#5_1), I'm checking it both in the
trunk and the branch.
Can someone look at the gcj.texi hunks?
./A
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.
Index: gcj.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/gcj.texi,v
retrieving revision 1.6
diff -u -p -r1.6 gcj.texi
--- gcj.texi 2001/02/24 03:36:22 1.6
+++ gcj.texi 2001/03/23 01:58:47
@@ -624,6 +624,20 @@ suppressed by @code{--CLASSPATH}), then
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 isnt' found.
+@end table
@node Encodings
@section Encodings
Index: java-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/java-tree.h,v
retrieving revision 1.103
diff -u -p -r1.103 java-tree.h
--- java-tree.h 2001/03/19 21:57:36 1.103
+++ java-tree.h 2001/03/23 01:58:52
@@ -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: jcf-parse.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/jcf-parse.c,v
retrieving revision 1.82
diff -u -p -r1.82 jcf-parse.c
--- jcf-parse.c 2001/03/20 22:57:20 1.82
+++ jcf-parse.c 2001/03/23 01:58:54
@@ -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,13 @@ 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 (!jcf->right_zip
+ /* Implement -fwarn-wrong-classeszip */
+ && (!flag_emit_class_files || flag_force_classes_archive_check))
+ fatal_error ("Incompatible classes archive: `%s'", jcf->filename);
+ }
else
all_class_list = tree_cons (NULL_TREE,
TYPE_NAME (current_class), all_class_list );
Index: jcf-reader.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/jcf-reader.c,v
retrieving revision 1.14
diff -u -p -r1.14 jcf-reader.c
--- jcf-reader.c 2001/01/24 08:08:36 1.14
+++ jcf-reader.c 2001/03/23 01:58:55
@@ -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,12 +210,19 @@ 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
PROCESS_OTHER_ATTRIBUTE(jcf, attribute_name, attribute_length);
@@ -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: jcf-write.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/jcf-write.c,v
retrieving revision 1.73
diff -u -p -r1.73 jcf-write.c
--- jcf-write.c 2001/03/17 20:44:23 1.73
+++ jcf-write.c 2001/03/23 01:59:03
@@ -346,10 +346,11 @@ static char *make_class_file_name PARAMS
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. */
@@ -3155,6 +3160,24 @@ append_synthetic_attribute (state)
PUT4 (0); /* Attribute length */
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
Index: jcf.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/jcf.h,v
retrieving revision 1.21
diff -u -p -r1.21 jcf.h
--- jcf.h 2001/03/19 21:57:37 1.21
+++ jcf.h 2001/03/23 01:59:04
@@ -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: lang-options.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/lang-options.h,v
retrieving revision 1.23
diff -u -p -r1.23 lang-options.h
--- lang-options.h 2001/02/24 03:28:39 1.23
+++ lang-options.h 2001/03/23 01:59:04
@@ -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: lang.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/lang.c,v
retrieving revision 1.60
diff -u -p -r1.60 lang.c
--- lang.c 2001/02/24 03:28:39 1.60
+++ lang.c 2001/03/23 01:59:05
@@ -144,6 +144,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;
@@ -164,7 +167,8 @@ lang_f_options[] =
{"use-divide-subroutine", &flag_use_divide_subroutine, 1},
{"use-boehm-gc", &flag_use_boehm_gc, 1},
{"hash-synchronization", &flag_hash_synchronization, 1},
- {"jni", &flag_jni, 1}
+ {"jni", &flag_jni, 1},
+ {"force-classes-archive-check", &flag_force_classes_archive_check, 1}
};
static struct string_option