From 57763f86c882f6b524e8f328a8056b1ac74be262 Mon Sep 17 00:00:00 2001 From: apbianco Date: Fri, 24 Aug 2001 17:40:54 +0000 Subject: [PATCH] 2001-08-23 Alexandre Petit-Bianco * jcf-parse.c (yyparse): Set magic to 0, don't issue error for a file smaller than 4 bytes. * parse.y (check_inner_circular_reference): New function. (check_circular_reference): Likewise. (array_initializer:): Accept {,}. (java_check_circular_reference): Rewritten using check_circular_reference and check_inner_circular_reference. (java_complete_expand_method): Unconditionally save and restore the unpurged exception list. (build_dot_class_method_invocation): Unmangle signature parameter. (http://gcc.gnu.org/ml/gcc-patches/2001-08/msg01417.html) git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@45156 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/java/ChangeLog | 13 ++++++ gcc/java/jcf-parse.c | 12 ++--- gcc/java/parse.y | 123 +++++++++++++++++++++++++++++++++++++++------------ 3 files changed, 113 insertions(+), 35 deletions(-) diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 45b145ef7ae..831a380d238 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,16 @@ +2001-08-23 Alexandre Petit-Bianco + + * jcf-parse.c (yyparse): Set magic to 0, don't issue error for a + file smaller than 4 bytes. + * parse.y (check_inner_circular_reference): New function. + (check_circular_reference): Likewise. + (array_initializer:): Accept {,}. + (java_check_circular_reference): Rewritten using + check_circular_reference and check_inner_circular_reference. + (java_complete_expand_method): Unconditionally save and restore + the unpurged exception list. + (build_dot_class_method_invocation): Unmangle signature parameter. + 2001-08-21 Tom Tromey * decl.c (init_decl_processing): Add `throws' field to method diff --git a/gcc/java/jcf-parse.c b/gcc/java/jcf-parse.c index e258167feb1..b52f1c11fb1 100644 --- a/gcc/java/jcf-parse.c +++ b/gcc/java/jcf-parse.c @@ -1088,7 +1088,7 @@ yyparse () for (node = current_file_list; node; node = TREE_CHAIN (node)) { unsigned char magic_string[4]; - uint32 magic; + uint32 magic = 0; tree name = TREE_VALUE (node); /* Skip already parsed files */ @@ -1110,11 +1110,11 @@ yyparse () input_filename = IDENTIFIER_POINTER (name); /* Figure what kind of file we're dealing with */ - if (fread (magic_string, 1, 4, finput) != 4) - fatal_io_error ("Premature end of input file %s", - IDENTIFIER_POINTER (name)); - fseek (finput, 0L, SEEK_SET); - magic = GET_u4 (magic_string); + if (fread (magic_string, 1, 4, finput) == 4) + { + fseek (finput, 0L, SEEK_SET); + magic = GET_u4 (magic_string); + } if (magic == 0xcafebabe) { CLASS_FILE_P (node) = 1; diff --git a/gcc/java/parse.y b/gcc/java/parse.y index d35a47dbc8e..b6054d418f7 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -141,6 +141,8 @@ static tree patch_invoke PARAMS ((tree, tree, tree)); static int maybe_use_access_method PARAMS ((int, tree *, tree *)); static tree lookup_method_invoke PARAMS ((int, tree, tree, tree, tree)); static tree register_incomplete_type PARAMS ((int, tree, tree, tree)); +static tree check_inner_circular_reference PARAMS ((tree, tree)); +static tree check_circular_reference PARAMS ((tree)); static tree obtain_incomplete_type PARAMS ((tree)); static tree java_complete_lhs PARAMS ((tree)); static tree java_complete_tree PARAMS ((tree)); @@ -1346,6 +1348,8 @@ abstract_method_declaration: array_initializer: OCB_TK CCB_TK { $$ = build_new_array_init ($1.location, NULL_TREE); } +| OCB_TK C_TK CCB_TK + { $$ = build_new_array_init ($1.location, NULL_TREE); } | OCB_TK variable_initializers CCB_TK { $$ = build_new_array_init ($1.location, $2); } | OCB_TK variable_initializers C_TK CCB_TK @@ -5219,6 +5223,80 @@ register_incomplete_type (kind, wfl, decl, ptr) return ptr; } +/* This checks for circular references with innerclasses. We start + from SOURCE and should never reach TARGET. Extended/implemented + types in SOURCE have their enclosing context checked not to reach + TARGET. When the last enclosing context of SOURCE is reached, its + extended/implemented types are also checked not to reach TARGET. + In case of error, WFL of the offending type is returned; NULL_TREE + otherwise. */ + +static tree +check_inner_circular_reference (source, target) + tree source; + tree target; +{ + tree basetype_vec = TYPE_BINFO_BASETYPES (source); + tree ctx, cl; + int i; + + if (!basetype_vec) + return NULL_TREE; + + for (i = 0; i < TREE_VEC_LENGTH (basetype_vec); i++) + { + tree su = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i)); + + if (inherits_from_p (su, target)) + return lookup_cl (TYPE_NAME (su)); + + for (ctx = DECL_CONTEXT (TYPE_NAME (su)); ctx; ctx = DECL_CONTEXT (ctx)) + { + /* An enclosing context shouldn't be TARGET */ + if (ctx == TYPE_NAME (target)) + return lookup_cl (TYPE_NAME (su)); + + /* When we reach the enclosing last context, start a check + on it, with the same target */ + if (! DECL_CONTEXT (ctx) && + (cl = check_inner_circular_reference (TREE_TYPE (ctx), target))) + return cl; + } + } + return NULL_TREE; +} + +/* Explore TYPE's `extends' clause member(s) and return the WFL of the + offending type if a circularity is detected. NULL_TREE is returned + otherwise. TYPE can be an interface or a class. */ + +static tree +check_circular_reference (type) + tree type; +{ + tree basetype_vec = TYPE_BINFO_BASETYPES (type); + int i; + + if (!basetype_vec) + return NULL_TREE; + + if (! CLASS_INTERFACE (TYPE_NAME (type))) + { + if (inherits_from_p (CLASSTYPE_SUPER (type), type)) + return lookup_cl (TYPE_NAME (type)); + return NULL_TREE; + } + + for (i = 0; i < TREE_VEC_LENGTH (basetype_vec); i++) + { + tree vec_elt = TREE_VEC_ELT (basetype_vec, i); + if (vec_elt && BINFO_TYPE (vec_elt) != object_type_node + && interface_of_p (type, BINFO_TYPE (vec_elt))) + return lookup_cl (TYPE_NAME (BINFO_TYPE (vec_elt))); + } + return NULL_TREE; +} + void java_check_circular_reference () { @@ -5226,30 +5304,15 @@ java_check_circular_reference () for (current = ctxp->class_list; current; current = TREE_CHAIN (current)) { tree type = TREE_TYPE (current); - if (CLASS_INTERFACE (current)) - { - /* Check all interfaces this class extends */ - tree basetype_vec = TYPE_BINFO_BASETYPES (type); - int n, i; + tree cl; - if (!basetype_vec) - return; - n = TREE_VEC_LENGTH (basetype_vec); - for (i = 0; i < n; i++) - { - tree vec_elt = TREE_VEC_ELT (basetype_vec, i); - if (vec_elt && BINFO_TYPE (vec_elt) != object_type_node - && interface_of_p (type, BINFO_TYPE (vec_elt))) - parse_error_context (lookup_cl (current), - "Cyclic interface inheritance"); - } - } - else - if (inherits_from_p (CLASSTYPE_SUPER (type), type)) - parse_error_context (lookup_cl (current), - "Cyclic class inheritance%s", - (cyclic_inheritance_report ? - cyclic_inheritance_report : "")); + cl = check_circular_reference (type); + if (! cl) + cl = check_inner_circular_reference (type, type); + if (cl) + parse_error_context (cl, "Cyclic class inheritance%s", + (cyclic_inheritance_report ? + cyclic_inheritance_report : "")); } } @@ -7918,10 +7981,9 @@ java_complete_expand_method (mdecl) current_this = (!METHOD_STATIC (mdecl) ? BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl)) : NULL_TREE); - /* Purge the `throws' list of unchecked exceptions. If we're doing - xref, save a copy of the list and re-install it later. */ - if (flag_emit_xref) - exception_copy = copy_list (DECL_FUNCTION_THROWS (mdecl)); + /* Purge the `throws' list of unchecked exceptions (we save a copy + of the list and re-install it later.) */ + exception_copy = copy_list (DECL_FUNCTION_THROWS (mdecl)); purge_unchecked_exceptions (mdecl); /* Install exceptions thrown with `throws' */ @@ -7985,8 +8047,7 @@ java_complete_expand_method (mdecl) abort (); /* Restore the copy of the list of exceptions if emitting xrefs. */ - if (flag_emit_xref) - DECL_FUNCTION_THROWS (mdecl) = exception_copy; + DECL_FUNCTION_THROWS (mdecl) = exception_copy; } /* For with each class for which there's code to generate. */ @@ -8657,6 +8718,10 @@ build_dot_class_method_invocation (type) else sig_id = DECL_NAME (TYPE_NAME (type)); + /* Ensure that the proper name separator is used */ + sig_id = unmangle_classname (IDENTIFIER_POINTER (sig_id), + IDENTIFIER_LENGTH (sig_id)); + s = build_string (IDENTIFIER_LENGTH (sig_id), IDENTIFIER_POINTER (sig_id)); return build_method_invocation (build_wfl_node (classdollar_identifier_node), -- 2.11.4.GIT