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 another friend crash



This keeps us from crashing on friend declarations that occur while
processing templates.

-- 
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

Index: testsuite/g++.old-deja/g++.pt/crash32.C
===================================================================
RCS file: crash32.C
diff -N crash32.C
*** /dev/null	Sat Dec  5 20:30:03 1998
--- crash32.C	Sat Mar 27 16:07:03 1999
***************
*** 0 ****
--- 1,13 ----
+ // Build don't link:
+ // Origin: Jason Merrill <jason@cygnus.com>
+ 
+ template <class T> struct A
+ {
+   struct B;
+ };
+ 
+ template<class T> struct C
+ {
+   friend typename A<T>::B;
+ };
+ 
Index: testsuite/g++.old-deja/g++.pt/friend38.C
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/testsuite/g++.old-deja/g++.pt/friend38.C,v
retrieving revision 1.2
diff -c -p -r1.2 friend38.C
*** friend38.C	1998/12/16 21:56:49	1.2
--- friend38.C	1999/03/28 00:07:04
***************
*** 2,10 ****
  
  // Overly simplified from testcase by "B. K. Oxley" <binkley@bigfoot.com>
  
- // crash test - XFAIL *-*-*
- 
  template<class P> struct foo {
    typedef P parent_type;
!   friend parent_type; // ERROR - template parameters cannot be friends
  };
--- 2,8 ----
  
  // Overly simplified from testcase by "B. K. Oxley" <binkley@bigfoot.com>
  
  template<class P> struct foo {
    typedef P parent_type;
!   friend parent_type; // ERROR - template parameters cannot be friends - XFAIL *-*-*
  };
Index: testsuite/cp/cp-tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.208
diff -c -p -r1.208 cp-tree.h
*** cp-tree.h	1999/03/24 01:10:03	1.208
--- cp-tree.h	1999/03/28 00:07:07
*************** extern void do_case				PROTO((tree, tree
*** 3025,3030 ****
--- 3025,3032 ----
  /* friend.c */
  extern int is_friend				PROTO((tree, tree));
  extern void make_friend_class			PROTO((tree, tree));
+ extern void add_friend                          PROTO((tree, tree));
+ extern void add_friends                         PROTO((tree, tree, tree));
  extern tree do_friend				PROTO((tree, tree, tree, tree, enum overload_flags, tree, int));
  
  /* in init.c */
Index: testsuite/cp/friend.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/friend.c,v
retrieving revision 1.42
diff -c -p -r1.42 friend.c
*** friend.c	1999/03/24 01:10:08	1.42
--- friend.c	1999/03/28 00:07:16
*************** Boston, MA 02111-1307, USA.  */
*** 27,35 ****
  #include "output.h"
  #include "toplev.h"
  
- static void add_friend PROTO((tree, tree));
- static void add_friends PROTO((tree, tree, tree));
- 
  /* Friend data structures are described in cp-tree.h.  */
  
  /* Returns non-zero if SUPPLICANT is a friend of TYPE.  */
--- 27,32 ----
*************** is_friend (type, supplicant)
*** 140,146 ****
  /* Add a new friend to the friends of the aggregate type TYPE.
     DECL is the FUNCTION_DECL of the friend being added.  */
  
! static void
  add_friend (type, decl)
       tree type, decl;
  {
--- 137,143 ----
  /* Add a new friend to the friends of the aggregate type TYPE.
     DECL is the FUNCTION_DECL of the friend being added.  */
  
! void
  add_friend (type, decl)
       tree type, decl;
  {
*************** add_friend (type, decl)
*** 176,190 ****
    DECL_FRIENDLIST (typedecl)
      = tree_cons (DECL_NAME (decl), build_tree_list (error_mark_node, decl),
  		 DECL_FRIENDLIST (typedecl));
!   DECL_BEFRIENDING_CLASSES (decl) 
!     = tree_cons (NULL_TREE, type,
! 		 DECL_BEFRIENDING_CLASSES (decl));
  }
  
  /* Declare that every member function NAME in FRIEND_TYPE
     (which may be NULL_TREE) is a friend of type TYPE.  */
  
! static void
  add_friends (type, name, friend_type)
       tree type, name, friend_type;
  {
--- 173,188 ----
    DECL_FRIENDLIST (typedecl)
      = tree_cons (DECL_NAME (decl), build_tree_list (error_mark_node, decl),
  		 DECL_FRIENDLIST (typedecl));
!   if (!uses_template_parms (type))
!     DECL_BEFRIENDING_CLASSES (decl) 
!       = tree_cons (NULL_TREE, type,
! 		   DECL_BEFRIENDING_CLASSES (decl));
  }
  
  /* Declare that every member function NAME in FRIEND_TYPE
     (which may be NULL_TREE) is a friend of type TYPE.  */
  
! void
  add_friends (type, name, friend_type)
       tree type, name, friend_type;
  {
*************** make_friend_class (type, friend_type)
*** 298,306 ****
  	= tree_cons (NULL_TREE, friend_type, CLASSTYPE_FRIEND_CLASSES (type));
        if (is_template_friend)
  	friend_type = TREE_TYPE (friend_type);
!       CLASSTYPE_BEFRIENDING_CLASSES (friend_type)
! 	= tree_cons (NULL_TREE, type, 
! 		     CLASSTYPE_BEFRIENDING_CLASSES (friend_type)); 
      }
  }
  
--- 296,305 ----
  	= tree_cons (NULL_TREE, friend_type, CLASSTYPE_FRIEND_CLASSES (type));
        if (is_template_friend)
  	friend_type = TREE_TYPE (friend_type);
!       if (!uses_template_parms (type))
! 	CLASSTYPE_BEFRIENDING_CLASSES (friend_type)
! 	  = tree_cons (NULL_TREE, type, 
! 		       CLASSTYPE_BEFRIENDING_CLASSES (friend_type)); 
      }
  }
  
Index: testsuite/cp/parse.y
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/parse.y,v
retrieving revision 1.109
diff -c -p -r1.109 parse.y
*** parse.y	1999/03/17 00:28:41	1.109
--- parse.y	1999/03/28 00:07:22
*************** component_decl_1:
*** 2482,2488 ****
  		     Therefore, the rules for components take care of
  		     this processing.  To avoid registering the
  		     components more than once, we send NULL_TREE up
! 		     here; that lets finish_member_declaration now
  		     that there is nothing to do.  */
  		  if (!$2)
  		    grok_x_components ($1.t);
--- 2482,2488 ----
  		     Therefore, the rules for components take care of
  		     this processing.  To avoid registering the
  		     components more than once, we send NULL_TREE up
! 		     here; that lets finish_member_declaration know
  		     that there is nothing to do.  */
  		  if (!$2)
  		    grok_x_components ($1.t);
Index: testsuite/cp/pt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/pt.c,v
retrieving revision 1.274
diff -c -p -r1.274 pt.c
*** pt.c	1999/03/25 13:28:39	1.274
--- pt.c	1999/03/28 00:07:27
*************** instantiate_class_template (type)
*** 4959,4990 ****
      {
        tree friends;
  
-       DECL_FRIENDLIST (typedecl)
- 	= tree_cons (TREE_PURPOSE (t), NULL_TREE, 
- 		     DECL_FRIENDLIST (typedecl));
- 
        for (friends = TREE_VALUE (t);
  	   friends != NULL_TREE;
  	   friends = TREE_CHAIN (friends))
! 	{
! 	  if (TREE_PURPOSE (friends) == error_mark_node)
! 	    {
! 	      TREE_VALUE (DECL_FRIENDLIST (typedecl))
! 		= tree_cons (error_mark_node, 
! 			     tsubst_friend_function (TREE_VALUE (friends),
! 						     args),
! 			     TREE_VALUE (DECL_FRIENDLIST (typedecl)));
! 	    }
! 	  else
! 	    {
! 	      TREE_VALUE (DECL_FRIENDLIST (typedecl))
! 		= tree_cons (tsubst (TREE_PURPOSE (friends), args, 
! 				     /*complain=*/1, NULL_TREE),
! 			     NULL_TREE,
! 			     TREE_VALUE (DECL_FRIENDLIST (typedecl)));
! 
! 	    }
! 	}
      }
  
    for (t = CLASSTYPE_FRIEND_CLASSES (pattern);
--- 4959,4977 ----
      {
        tree friends;
  
        for (friends = TREE_VALUE (t);
  	   friends != NULL_TREE;
  	   friends = TREE_CHAIN (friends))
! 	if (TREE_PURPOSE (friends) == error_mark_node)
! 	  add_friend (type, 
! 		      tsubst_friend_function (TREE_VALUE (friends),
! 					      args));
! 	else
! 	  add_friends (type, 
! 		       tsubst_copy (TREE_PURPOSE (t), args,
! 				    /*complain=*/1, NULL_TREE),
! 		       tsubst (TREE_PURPOSE (friends), args,
! 			       /*complain=*/1, NULL_TREE));
      }
  
    for (t = CLASSTYPE_FRIEND_CLASSES (pattern);


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