This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

(C++) patch for anon union access control


We were erroneously treating unnamed unions used to declare objects as
though they were anonymous unions.  This also fixes a crash when trying to
do access control on a member of a file-scope anonymous union.

1999-03-06  Jason Merrill  <jason@yorick.cygnus.com>

	* 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.

Index: cp-tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.203
diff -c -p -r1.203 cp-tree.h
*** cp-tree.h	1999/03/05 16:38:50	1.203
--- cp-tree.h	1999/03/07 01:38:16
*************** struct lang_type
*** 725,735 ****
        unsigned non_aggregate : 1;
        unsigned is_partial_instantiation : 1;
        unsigned has_mutable : 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;
      } type_flags;
  
    int n_ancestors;
--- 725,736 ----
        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 : 9;
      } type_flags;
  
    int n_ancestors;
*************** extern int flag_new_for_scope;
*** 1708,1720 ****
  
  #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)))
  
  #define UNKNOWN_TYPE LANG_TYPE
  
--- 1709,1722 ----
  
  #define ANON_UNION_P(NODE) (DECL_NAME (NODE) == 0)
  
! /* 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
  
Index: decl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl.c,v
retrieving revision 1.318
diff -c -p -r1.318 decl.c
*** decl.c	1999/03/05 16:38:52	1.318
--- decl.c	1999/03/07 01:38:16
*************** check_tag_decl (declspecs)
*** 6740,6747 ****
       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.  */;
    else if (ob_modifier)
      {
        if (ob_modifier == ridpointers[(int) RID_INLINE]
--- 6740,6757 ----
       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");
! 
!   /* 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]
Index: search.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/search.c,v
retrieving revision 1.81
diff -c -p -r1.81 search.c
*** search.c	1999/03/05 16:38:54	1.81
--- search.c	1999/03/07 01:38:16
***************
*** 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.
     Contributed by Michael Tiemann (tiemann@cygnus.com)
  
  This file is part of GNU CC.
--- 1,6 ----
  /* Breadth-first and depth-first routines for
     searching multiple-inheritance lattice for GNU C++.
!    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.
*************** compute_access (basetype_path, field)
*** 667,672 ****
--- 667,677 ----
        && 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)
*************** compute_access (basetype_path, field)
*** 677,683 ****
      {
        /* Are we (or an enclosing scope) friends with the class that has
           FIELD? */
!       if (TYPE_P (context) && is_friend (context, previous_scope))
  	PUBLIC_RETURN;
  
        /* If it's private, it's private, you letch.  */
--- 682,688 ----
      {
        /* Are we (or an enclosing scope) friends with the class that has
           FIELD? */
!       if (is_friend (context, previous_scope))
  	PUBLIC_RETURN;
  
        /* If it's private, it's private, you letch.  */
*************** compute_access (basetype_path, field)
*** 693,699 ****
  	{
  	  if (current_class_type
  	      && (static_mem || DECL_CONSTRUCTOR_P (field))
- 	      && TYPE_P (context)
  	      && ACCESSIBLY_DERIVED_FROM_P (context, current_class_type))
  	    PUBLIC_RETURN;
  	  else
--- 698,703 ----
*************** compute_access (basetype_path, field)
*** 755,761 ****
  
    if (access == access_default_node)
      {
!       if (TYPE_P (context) && is_friend (context, previous_scope))
  	access = access_public_node;
        else if (TREE_PRIVATE (field))
  	access = access_private_node;
--- 759,765 ----
  
    if (access == access_default_node)
      {
!       if (is_friend (context, previous_scope))
  	access = access_public_node;
        else if (TREE_PRIVATE (field))
  	access = access_private_node;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]