[C++ PATCH, committed] Fix PR5421

Kriang Lerdsuwanakij lerdsuwa@users.sourceforge.net
Wed Jul 16 15:45:00 GMT 2003


This patch fixes PR5421 which is an ICE on legal friend declaration
of the form

    friend void B::b<T>();

We have 2 separate problems handling the above code.  First,
a particular call to 'grokfndecl' in 'grokdeclarator' fails to
to deal with TEMPLATE_ID_EXPR.  Second, we shouldn't call
'push_template_decl' to build a TEMPLATE_DECL for such friend.
It's already a specialization of a function template.

Tested on i686-pc-linux-gnu.  Committed to trunk as obvious.

--Kriang


2003-07-16  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>

	PR c++/5421
	* decl.c (grokdeclarator): Handle TEMPLATE_ID_EXPR if friend
	is a member of other class.
	* friend.c (do_friend): Don't build TEMPLATE_DECL if friend
	is a specialization of function template.

2003-07-16  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>

	PR c++/5421
	* g++.dg/template/friend21.C: New test.


diff -cprN gcc-main-save/gcc/cp/decl.c gcc-main-new/gcc/cp/decl.c
*** gcc-main-save/gcc/cp/decl.c	Tue Jul 15 19:28:46 2003
--- gcc-main-new/gcc/cp/decl.c	Wed Jul 16 20:52:36 2003
*************** grokdeclarator (tree declarator,
*** 11492,11498 ****
  	       members of other classes.  */
  	    /* All method decls are public, so tell grokfndecl to set
  	       TREE_PUBLIC, also.  */
! 	    decl = grokfndecl (ctype, type, declarator, declarator,
  			       virtualp, flags, quals, raises,
  			       friendp ? -1 : 0, friendp, 1, 0, funcdef_flag,
  			       template_count, in_namespace);
--- 11492,11501 ----
  	       members of other classes.  */
  	    /* All method decls are public, so tell grokfndecl to set
  	       TREE_PUBLIC, also.  */
! 	    decl = grokfndecl (ctype, type,
! 			       TREE_CODE (declarator) != TEMPLATE_ID_EXPR
! 			       ? declarator : dname,
! 			       declarator,
  			       virtualp, flags, quals, raises,
  			       friendp ? -1 : 0, friendp, 1, 0, funcdef_flag,
  			       template_count, in_namespace);
diff -cprN gcc-main-save/gcc/cp/friend.c gcc-main-new/gcc/cp/friend.c
*** gcc-main-save/gcc/cp/friend.c	Tue Jul  8 22:34:48 2003
--- gcc-main-new/gcc/cp/friend.c	Wed Jul 16 20:57:07 2003
*************** do_friend (tree ctype, tree declarator, 
*** 359,364 ****
--- 359,366 ----
  
        if (is_friend_template)
  	decl = DECL_TI_TEMPLATE (push_template_decl (decl));
+       else if (DECL_TEMPLATE_INFO (decl))
+ 	;
        else if (template_class_depth (current_class_type))
  	decl = push_template_decl_real (decl, /*is_friend=*/1);
  
diff -cprN gcc-main-save/gcc/testsuite/g++.dg/template/friend21.C gcc-main-new/gcc/testsuite/g++.dg/template/friend21.C
*** gcc-main-save/gcc/testsuite/g++.dg/template/friend21.C	Thu Jan  1 07:00:00 1970
--- gcc-main-new/gcc/testsuite/g++.dg/template/friend21.C	Wed Jul 16 21:24:24 2003
***************
*** 0 ****
--- 1,16 ----
+ // { dg-do compile }
+ 
+ // Origin: ajl13@bellatlantic.net
+ 
+ // PR c++/5421: ICE for specialization of member function template
+ // as friend.
+ 
+ struct B {
+   template <class T> void b();
+ };
+ 
+ template <class T> class A {
+   friend void B::b<T>();
+ };
+ 
+ static A<int> a;



More information about the Gcc-patches mailing list