This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Fix PR8099
- From: Kriang Lerdsuwanakij <lerdsuwa at users dot sourceforge dot net>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 26 Nov 2002 19:40:01 +0700
- Subject: [C++ PATCH] Fix PR8099
Hi
The following patch fixes PR8099. The test condition for
partial specialization is too strict. 14.5.3p7 intends to
prohibit only template friends that declare a partial
specialization, such as
template <class T> friend class C<T*>;
not a partial specialization
friend class D<1, P>;
where P is a template parameter.
Bootstrapped and tested with no regressions on i686-pc-linux-gnu.
OK to commit to trunk?
--Kriang
2002-11-26 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
PR c++/8099
* friend.c (make_friend_class): Allow partial specialization
when declaration is not a template friend.
2002-11-26 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
PR c++/8099
* g++.dg/template/friend8.C: Expect error.
diff -cprN gcc-main-save/gcc/cp/friend.c gcc-main-new/gcc/cp/friend.c
*** gcc-main-save/gcc/cp/friend.c Tue Nov 26 13:57:59 2002
--- gcc-main-new/gcc/cp/friend.c Tue Nov 26 17:38:27 2002
*************** make_friend_class (type, friend_type)
*** 203,226 ****
return;
}
- if (CLASS_TYPE_P (friend_type)
- && CLASSTYPE_TEMPLATE_SPECIALIZATION (friend_type)
- && uses_template_parms (friend_type))
- {
- /* [temp.friend]
-
- Friend declarations shall not declare partial
- specializations. */
- error ("partial specialization `%T' declared `friend'",
- friend_type);
- return;
- }
-
if (processing_template_decl > template_class_depth (type))
/* If the TYPE is a template then it makes sense for it to be
friends with itself; this means that each instantiation is
friends with all other instantiations. */
! is_template_friend = 1;
else if (same_type_p (type, friend_type))
{
pedwarn ("class `%T' is implicitly friends with itself",
--- 203,227 ----
return;
}
if (processing_template_decl > template_class_depth (type))
/* If the TYPE is a template then it makes sense for it to be
friends with itself; this means that each instantiation is
friends with all other instantiations. */
! {
! if (CLASS_TYPE_P (friend_type)
! && CLASSTYPE_TEMPLATE_SPECIALIZATION (friend_type)
! && uses_template_parms (friend_type))
! {
! /* [temp.friend]
! Friend declarations shall not declare partial
! specializations. */
! error ("partial specialization `%T' declared `friend'",
! friend_type);
! return;
! }
!
! is_template_friend = 1;
! }
else if (same_type_p (type, friend_type))
{
pedwarn ("class `%T' is implicitly friends with itself",
diff -cprN gcc-main-save/gcc/testsuite/g++.dg/template/friend8.C gcc-main-new/gcc/testsuite/g++.dg/template/friend8.C
*** gcc-main-save/gcc/testsuite/g++.dg/template/friend8.C Thu Jan 1 07:00:00 1970
--- gcc-main-new/gcc/testsuite/g++.dg/template/friend8.C Tue Nov 26 18:05:16 2002
***************
*** 0 ****
--- 1,18 ----
+ // { dg-do compile }
+ // Origin: Wolfgang Bangerth <bangerth@ticam.utexas.edu>
+
+ // PR c++/8099
+ // Partial specialization as friend class
+
+ template <int N, typename T> struct X;
+ template <typename T> struct X<1,T>;
+
+ template <typename P> class Y {
+ static int i;
+ template <int N, typename T> friend struct X;
+ friend struct X<1,P>;
+ };
+
+ template <typename T> struct X<1,T> {
+ X () { Y<T>::i; }; // access private field
+ };