This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH, committed] Fix PR5421
- From: Kriang Lerdsuwanakij <lerdsuwa at users dot sourceforge dot net>
- To: <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 16 Jul 2003 22:52:39 +0700 (ICT)
- Subject: [C++ PATCH, committed] Fix PR5421
- Reply-to: <lerdsuwa at users dot sourceforge dot net>
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;