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]
Other format: [Raw text]

C++ PATCH: PR 22139


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.


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