From: Bryce McKinlay Date: Sun, 27 Jun 2004 15:30:06 +0000 (+0000) Subject: re PR java/15715 (member interfaces are always static) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0f6cd83f96821808017f3b2318da521a9c29ed62;p=gcc.git re PR java/15715 (member interfaces are always static) 2004-06-26 Bryce McKinlay PR java/15715. * parse.y (create_interface): Set correct access modifiers for interfaces. * jcf-write.c (get_classfile_modifiers): New function. (generate_classfile): Use get_classfile_modifiers, not get_access_flags. 2004-06-26 Bryce McKinlay * parse.y (register_incomplete_type): Set JDEP_ENCLOSING for "super" dependency to current parser context, not NULL_TREE, for top-level classes. (jdep_resolve_class): Enable member access check for all inner class dependencies. From-SVN: r83734 --- diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index e3e1964cb55..e7594069ea7 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,20 @@ +2004-06-26 Bryce McKinlay + + PR java/15715. + * parse.y (create_interface): Set correct access modifiers for + interfaces. + * jcf-write.c (get_classfile_modifiers): New function. + (generate_classfile): Use get_classfile_modifiers, not + get_access_flags. + +2004-06-26 Bryce McKinlay + + * parse.y (register_incomplete_type): Set JDEP_ENCLOSING for "super" + dependency to current parser context, not NULL_TREE, for top-level + classes. + (jdep_resolve_class): Enable member access check for all inner + class dependencies. + 2004-06-26 Bryce McKinlay * parse.y (qualify_and_find): Pass type decl, not identifier, to diff --git a/gcc/java/jcf-write.c b/gcc/java/jcf-write.c index b04d55985d9..8ead8866181 100644 --- a/gcc/java/jcf-write.c +++ b/gcc/java/jcf-write.c @@ -304,6 +304,7 @@ static void perform_relocations (struct jcf_partial *); static void init_jcf_state (struct jcf_partial *, struct obstack *); static void init_jcf_method (struct jcf_partial *, tree); static void release_jcf_state (struct jcf_partial *); +static int get_classfile_modifiers (tree class); static struct chunk * generate_classfile (tree, struct jcf_partial *); static struct jcf_handler *alloc_handler (struct jcf_block *, struct jcf_block *, @@ -2886,6 +2887,32 @@ release_jcf_state (struct jcf_partial *state) obstack_free (state->chunk_obstack, state->first); } +/* Get the access flags (modifiers) of a class (TYPE_DECL) to be used in the + access_flags field of the class file header. */ + +static int get_classfile_modifiers (tree class) +{ + /* These are the flags which are valid class file modifiers. + See JVMS2 S4.1. */ + int valid_toplevel_class_flags = ACC_PUBLIC | ACC_FINAL | ACC_SUPER | + ACC_INTERFACE | ACC_ABSTRACT; + int flags = get_access_flags (class); + + /* ACC_SUPER should always be set, except for interfaces. */ + if (! (flags & ACC_INTERFACE)) + flags |= ACC_SUPER; + + /* A protected member class becomes public at the top level. */ + if (flags & ACC_PROTECTED) + flags |= ACC_PUBLIC; + + /* Filter out flags that are not valid for a class or interface in the + top-level access_flags field. */ + flags &= valid_toplevel_class_flags; + + return flags; +} + /* Generate and return a list of chunks containing the class CLAS in the .class file representation. The list can be written to a .class file using write_chunks. Allocate chunks from obstack WORK. */ @@ -2921,9 +2948,7 @@ generate_classfile (tree clas, struct jcf_partial *state) else i = 8 + 2 * total_supers; ptr = append_chunk (NULL, i, state); - i = get_access_flags (TYPE_NAME (clas)); - if (! (i & ACC_INTERFACE)) - i |= ACC_SUPER; + i = get_classfile_modifiers (TYPE_NAME (clas)); PUT2 (i); /* access_flags */ i = find_class_constant (&state->cpool, clas); PUT2 (i); /* this_class */ if (clas == object_type_node) diff --git a/gcc/java/parse.y b/gcc/java/parse.y index e4ad4cd2e22..4d7f2186542 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -3852,6 +3852,13 @@ create_interface (int flags, tree id, tree super) /* Create a new decl if DECL is NULL, otherwise fix it */ decl = maybe_create_class_interface_decl (decl, raw_name, q_name, id); + /* Interfaces are always abstract. */ + flags |= ACC_ABSTRACT; + + /* Inner interfaces are always static. */ + if (INNER_CLASS_DECL_P (decl)) + flags |= ACC_STATIC; + /* Set super info and mark the class a complete */ set_super_info (ACC_INTERFACE | flags, TREE_TYPE (decl), object_type_node, ctxp->interface_number); @@ -5187,12 +5194,9 @@ register_incomplete_type (int kind, tree wfl, tree decl, tree ptr) JDEP_MISC (new) = NULL_TREE; /* For some dependencies, set the enclosing class of the current class to be the enclosing context */ - if ((kind == JDEP_INTERFACE || kind == JDEP_ANONYMOUS) + if ((kind == JDEP_INTERFACE || kind == JDEP_ANONYMOUS || kind == JDEP_SUPER) && GET_ENCLOSING_CPC ()) JDEP_ENCLOSING (new) = TREE_VALUE (GET_ENCLOSING_CPC ()); - else if (kind == JDEP_SUPER) - JDEP_ENCLOSING (new) = (GET_ENCLOSING_CPC () ? - TREE_VALUE (GET_ENCLOSING_CPC ()) : NULL_TREE); else JDEP_ENCLOSING (new) = GET_CPC (); JDEP_GET_PATCH (new) = (tree *)NULL; @@ -5512,7 +5516,7 @@ jdep_resolve_class (jdep *dep) if (!decl) complete_class_report_errors (dep); - else if (PURE_INNER_CLASS_DECL_P (decl)) + else if (INNER_CLASS_DECL_P (decl)) { tree inner = TREE_TYPE (decl); if (! CLASS_LOADED_P (inner))