re PR java/1213 (gcj should check for incorrect CLASSPATH)
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
This commit is contained in:
parent
b64295c4d3
commit
b124f72e29
9 changed files with 106 additions and 14 deletions
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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++)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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" },
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue