This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: PR 22139
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 17 Jul 2005 15:32:34 -0700
- Subject: C++ PATCH: PR 22139
- Reply-to: mark at codesourcery dot com
This patch fixes a 4.0 regression -- but I'm not 100% sure it wasn't
latent before. The problem was that the special case of a friend
function which is a template from the point of view of the compiler,
but not from the point of view of the language, was not being handled
correctly.
Tested on x86_64-unknown-linug-gnu, applied on the mainline and on the
branch.
--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
2005-07-17 Mark Mitchell <mark@codesourcery.com>
PR c++/22139
* cp-tree.h (DECL_TEMPLATE_INFO): Improve documentation.
* decl.c (duplicate_decls): Re-register template specializations
for functions that have DECL_TEMLPLATE_INFO, even if they do not
have DECL_TEMPLATE_INSTANTIATION set.
2005-07-17 Mark Mitchell <mark@codesourcery.com>
PR c++/22139
* g++.dg/template/friend36.C: New test.
Index: gcc/testsuite/g++.dg/template/friend36.C
===================================================================
RCS file: gcc/testsuite/g++.dg/template/friend36.C
diff -N gcc/testsuite/g++.dg/template/friend36.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/template/friend36.C 17 Jul 2005 21:00:19 -0000
***************
*** 0 ****
--- 1,10 ----
+ // PR c++/22139
+ // { dg-options "--param ggc-min-expand=0 --param ggc-min-heapsize=0" }
+
+ template <int rank, int dim> class Tensor;
+ template <int rank, int dim> struct SymmetricTensor {
+ SymmetricTensor (const Tensor<2,dim> &t);
+ friend void foo();
+ };
+ template <> SymmetricTensor<2,2>::SymmetricTensor (const Tensor<2,2> &t) {}
+ template <> SymmetricTensor<2,3>::SymmetricTensor (const Tensor<2,3> &t) {}
Index: gcc/cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1154
diff -c -5 -p -r1.1154 cp-tree.h
*** gcc/cp/cp-tree.h 15 Jul 2005 16:10:04 -0000 1.1154
--- gcc/cp/cp-tree.h 17 Jul 2005 21:00:19 -0000
*************** extern void decl_shadowed_for_var_insert
*** 2054,2065 ****
/* True if on the deferred_fns (see decl2.c) list. */
#define DECL_DEFERRED_FN(DECL) \
(DECL_LANG_SPECIFIC (DECL)->decl_flags.deferred)
! /* For a VAR_DECL, FUNCTION_DECL, TYPE_DECL or TEMPLATE_DECL:
! template-specific information. */
#define DECL_TEMPLATE_INFO(NODE) \
(DECL_LANG_SPECIFIC (VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK (NODE)) \
->decl_flags.u.template_info)
/* For a VAR_DECL, indicates that the variable has been processed.
--- 2054,2081 ----
/* True if on the deferred_fns (see decl2.c) list. */
#define DECL_DEFERRED_FN(DECL) \
(DECL_LANG_SPECIFIC (DECL)->decl_flags.deferred)
! /* If non-NULL for a VAR_DECL, FUNCTION_DECL, TYPE_DECL or
! TEMPLATE_DECL, the entity is a template specialization. In that
! case, DECL_TEMPLATE_INFO is a TREE_LIST, whose TREE_PURPOSE is the
! TEMPLATE_DECL of which this entity is a specialization. The TREE_
! TREE_VALUE is the template arguments used to specialize the
! template.
!
! In general, DECL_TEMPLATE_INFO is non-NULL only if
! DECL_USE_TEMPLATE is non-zero. However, for friends, we sometimes
! have DECL_TEMPLATE_INFO even when DECL_USE_TEMPLATE is zero.
! Consider:
!
! template <typename T> struct S { friend void f(T) {} };
!
! In this case, S<int>::f is, from the point of view of the compiler,
! an instantiation of a template -- but, from the point of view of
! the language, each instantiation of S results in a wholly unrelated
! global function f. */
#define DECL_TEMPLATE_INFO(NODE) \
(DECL_LANG_SPECIFIC (VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK (NODE)) \
->decl_flags.u.template_info)
/* For a VAR_DECL, indicates that the variable has been processed.
Index: gcc/cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1413
diff -c -5 -p -r1.1413 decl.c
*** gcc/cp/decl.c 8 Jul 2005 23:36:56 -0000 1.1413
--- gcc/cp/decl.c 17 Jul 2005 21:00:19 -0000
*************** duplicate_decls (tree newdecl, tree oldd
*** 1836,1846 ****
function_size - sizeof (struct tree_common));
memcpy ((char *) olddecl + sizeof (struct tree_decl_common),
(char *) newdecl + sizeof (struct tree_decl_common),
sizeof (struct tree_function_decl) - sizeof (struct tree_decl_common));
! if (DECL_TEMPLATE_INSTANTIATION (newdecl))
/* If newdecl is a template instantiation, it is possible that
the following sequence of events has occurred:
o A friend function was declared in a class template. The
class template was instantiated.
--- 1836,1846 ----
function_size - sizeof (struct tree_common));
memcpy ((char *) olddecl + sizeof (struct tree_decl_common),
(char *) newdecl + sizeof (struct tree_decl_common),
sizeof (struct tree_function_decl) - sizeof (struct tree_decl_common));
! if (DECL_TEMPLATE_INFO (newdecl))
/* If newdecl is a template instantiation, it is possible that
the following sequence of events has occurred:
o A friend function was declared in a class template. The
class template was instantiated.