PATCH for friend/template/inline link-failure

Mark Mitchell mark@markmitchell.com
Tue Sep 1 13:09:00 GMT 1998


The following test-case would not link with -g, due to confusion
involving DECL_EXTERNAL.  The fix is to treat friend pseudo-templates
like real templates, when it comes to import_export_decl.

-- 
Mark Mitchell 			mark@markmitchell.com
Mark Mitchell Consulting	http://www.markmitchell.com

1998-09-01  Mark Mitchell  <mark@markmitchell.com>

	* cp-tree.h (DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION): New macro.
	* decl2.c (import_export_decl): Likewise.
	* pt.c (instantiate_decl): Use it.

Index: testsuite/g++.old-deja/g++.pt/friend33.C
===================================================================
RCS file: friend33.C
diff -N friend33.C
*** /dev/null	Mon Dec 31 20:00:00 1979
--- friend33.C	Tue Sep  1 11:50:28 1998
***************
*** 0 ****
--- 1,28 ----
+ // Build don't run:
+ // Special g++ Options: -g
+ 
+ template <class P1>
+ struct S1
+ {
+   struct SS1
+   {
+   };
+   friend void Foo (const SS1& ss1)
+     {
+     }
+ };
+ 
+ template <class P1>
+ void Foo(const S1<P1>& s1)
+ {
+   typedef typename S1<P1>::SS1 TYPE;
+   TYPE t;
+   Foo(t);
+ }
+ 
+ int main ()
+ {
+   S1<double> obj;
+   Foo(obj);
+ }
+ 
Index: cp/cp-tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.127
diff -c -p -r1.127 cp-tree.h
*** cp-tree.h	1998/08/31 12:54:14	1.127
--- cp-tree.h	1998/09/01 18:50:43
*************** extern int flag_new_for_scope;
*** 1719,1724 ****
--- 1719,1734 ----
  #define SET_CLASSTYPE_EXPLICIT_INSTANTIATION(NODE) \
    (CLASSTYPE_USE_TEMPLATE(NODE) = 3)
  
+ /* Non-zero if DECL is a friend function which is an instantiation
+    from the point of view of the compiler, but not from the point of
+    view of the language.  For example given:
+       template <class T> struct S { friend void f(T) {}; };
+    the declaration of `void f(int)' generated when S<int> is
+    instantiated will not be a DECL_TEMPLATE_INSTANTIATION, but will be
+    a DECL_FRIEND_PSUEDO_TEMPLATE_INSTANTIATION.  */
+ #define DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION(DECL) \
+   (DECL_TEMPLATE_INFO (DECL) && !DECL_USE_TEMPLATE (DECL))
+ 
  /* Non-zero iff we are currently processing a declaration for an
     entity with its own template parameter list, and which is not a
     full specialization.  */
Index: cp/decl2.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl2.c,v
retrieving revision 1.126
diff -c -p -r1.126 decl2.c
*** decl2.c	1998/09/01 09:56:37	1.126
--- decl2.c	1998/09/01 18:50:57
*************** import_export_decl (decl)
*** 2837,2846 ****
    if (DECL_INTERFACE_KNOWN (decl))
      return;
  
!   if (DECL_TEMPLATE_INSTANTIATION (decl))
      {
        DECL_NOT_REALLY_EXTERN (decl) = 1;
!       if (DECL_IMPLICIT_INSTANTIATION (decl)
  	  && (flag_implicit_templates || DECL_THIS_INLINE (decl)))
  	{
  	  if (!TREE_PUBLIC (decl))
--- 2837,2848 ----
    if (DECL_INTERFACE_KNOWN (decl))
      return;
  
!   if (DECL_TEMPLATE_INSTANTIATION (decl)
!       || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl))
      {
        DECL_NOT_REALLY_EXTERN (decl) = 1;
!       if ((DECL_IMPLICIT_INSTANTIATION (decl)
! 	   || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl))
  	  && (flag_implicit_templates || DECL_THIS_INLINE (decl)))
  	{
  	  if (!TREE_PUBLIC (decl))
Index: cp/pt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/pt.c,v
retrieving revision 1.192
diff -c -p -r1.192 pt.c
*** pt.c	1998/08/30 10:59:18	1.192
--- pt.c	1998/09/01 18:51:20
*************** instantiate_decl (d)
*** 7940,7947 ****
  	    we don't need to look any further.  That's what the check for
  	    DECL_INITIAL is for.  */
  	|| (TREE_CODE (d) == FUNCTION_DECL
! 	    && DECL_TEMPLATE_INFO (td) 
! 	    && !DECL_TEMPLATE_SPECIALIZATION (td)
  	    && !DECL_INITIAL (DECL_TEMPLATE_RESULT (td)));
         )
      {
--- 7940,7946 ----
  	    we don't need to look any further.  That's what the check for
  	    DECL_INITIAL is for.  */
  	|| (TREE_CODE (d) == FUNCTION_DECL
! 	    && DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (td)
  	    && !DECL_INITIAL (DECL_TEMPLATE_RESULT (td)));
         )
      {



More information about the Gcc-patches mailing list