diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c85bebf64c3..602fa44b875 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,15 @@ 1999-03-06 Jason Merrill + * cp-tree.h (struct lang_type): Add anon_union field. + (ANON_UNION_TYPE_P): Use it instead of examining type. + (SET_ANON_UNION_TYPE_P): New macro. + * decl.c (check_tag_decl): Use it. + + * search.c (compute_access): Handle non-type contexts earlier, and + handle NULL_TREE. + + * tree.c (build_exception_variant): Use copy_to_permanent. + * decl2.c (setup_initp): Give statics with no priority the default priority here. (do_dtors, do_ctors, finish_file): Remove special handling of diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index ab33fad0e9d..fdc981f91e9 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -725,11 +725,12 @@ struct lang_type unsigned non_aggregate : 1; unsigned is_partial_instantiation : 1; unsigned has_mutable : 1; + unsigned anon_union : 1; /* The MIPS compiler gets it wrong if this struct also does not fill out to a multiple of 4 bytes. Add a member `dummy' with new bits if you go over the edge. */ - unsigned dummy : 10; + unsigned dummy : 9; } type_flags; int n_ancestors; @@ -1708,13 +1709,14 @@ extern int flag_new_for_scope; #define ANON_UNION_P(NODE) (DECL_NAME (NODE) == 0) -/* Nonzero if TYPE is an anonymous union type. We're careful - accessing TYPE_IDENTIFIER because some built-in types, like - pointer-to-member types, do not have TYPE_NAME. */ -#define ANON_UNION_TYPE_P(TYPE) \ - (TREE_CODE (TYPE) == UNION_TYPE \ - && TYPE_NAME (TYPE) \ - && ANON_AGGRNAME_P (TYPE_IDENTIFIER (TYPE))) +/* Nonzero if TYPE is an anonymous union type. We have to use a flag for + this because "A union for which objects or pointers are declared is not + an anonymous union" [class.union]. */ +#define ANON_UNION_TYPE_P(NODE) \ + (TYPE_LANG_SPECIFIC (NODE) \ + && TYPE_LANG_SPECIFIC (NODE)->type_flags.anon_union) +#define SET_ANON_UNION_TYPE_P(NODE) \ + (TYPE_LANG_SPECIFIC (NODE)->type_flags.anon_union = 1) #define UNKNOWN_TYPE LANG_TYPE diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index cf7ce614635..a386735b082 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -6740,8 +6740,18 @@ check_tag_decl (declspecs) Until we have a good way of detecting the latter, don't warn. */ if (t == NULL_TREE && ! current_class_type) pedwarn ("declaration does not declare anything"); - else if (t && ANON_UNION_TYPE_P (t)) - /* Anonymous unions are objects, so they can have specifiers. */; + + /* Check for an anonymous union. We're careful + accessing TYPE_IDENTIFIER because some built-in types, like + pointer-to-member types, do not have TYPE_NAME. */ + else if (t && TREE_CODE (t) == UNION_TYPE + && TYPE_NAME (t) + && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))) + { + /* Anonymous unions are objects, so they can have specifiers. */; + SET_ANON_UNION_TYPE_P (t); + } + else if (ob_modifier) { if (ob_modifier == ridpointers[(int) RID_INLINE] diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 907c9d34c59..369a06f84b5 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -1,6 +1,6 @@ /* Breadth-first and depth-first routines for searching multiple-inheritance lattice for GNU C++. - Copyright (C) 1987, 89, 92-97, 1998 Free Software Foundation, Inc. + Copyright (C) 1987, 89, 92-97, 1998, 1999 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) This file is part of GNU CC. @@ -667,6 +667,11 @@ compute_access (basetype_path, field) && TREE_CODE (field) == FIELD_DECL) context = TYPE_CONTEXT (context); + /* If we aren't a real class member (e.g. we're from a namespace-scope + anonymous union), there's no access control. */ + if (context == NULL_TREE || ! TYPE_P (context)) + PUBLIC_RETURN; + /* Virtual function tables are never private. But we should know that we are looking for this, and not even try to hide it. */ if (DECL_NAME (field) && VFIELD_NAME_P (DECL_NAME (field)) == 1) @@ -677,7 +682,7 @@ compute_access (basetype_path, field) { /* Are we (or an enclosing scope) friends with the class that has FIELD? */ - if (TYPE_P (context) && is_friend (context, previous_scope)) + if (is_friend (context, previous_scope)) PUBLIC_RETURN; /* If it's private, it's private, you letch. */ @@ -693,7 +698,6 @@ compute_access (basetype_path, field) { if (current_class_type && (static_mem || DECL_CONSTRUCTOR_P (field)) - && TYPE_P (context) && ACCESSIBLY_DERIVED_FROM_P (context, current_class_type)) PUBLIC_RETURN; else @@ -755,7 +759,7 @@ compute_access (basetype_path, field) if (access == access_default_node) { - if (TYPE_P (context) && is_friend (context, previous_scope)) + if (is_friend (context, previous_scope)) access = access_public_node; else if (TREE_PRIVATE (field)) access = access_private_node; diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 6d6fc43cccf..b93d9bd6fd0 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1517,12 +1517,7 @@ build_exception_variant (type, raises) v = build_type_copy (type); if (raises && ! TREE_PERMANENT (raises)) - { - push_obstacks_nochange (); - end_temporary_allocation (); - raises = copy_list (raises); - pop_obstacks (); - } + raises = copy_to_permanent (raises); TYPE_RAISES_EXCEPTIONS (v) = raises; return v;