This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
(C++) patch for anon union access control
- To: egcs-patches at cygnus dot com
- Subject: (C++) patch for anon union access control
- From: Jason Merrill <jason at cygnus dot com>
- Date: Sat, 6 Mar 1999 17:41:09 -0800
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;