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 7053


This patch fixes PR c++/7053, which, coincidentally I'd fixed on the
mainline yesterday with one of my other patches.  I've applied these
bits to the branch, after testing them on i686-pc-linux-gnu.  I've
also added the testcase to the mainline.

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2003-07-14  Mark Mitchell  <mark@codesourcery.com>

	PR c++/7053
	* pt.c (unregister_specialization): Rename to ...
	(reregister_specialization): ... this.
	(tsubst_friend_function): Use it.
	(regenerate_decl_from_template): Likewise.

2003-07-14  Mark Mitchell  <mark@codesourcery.com>

	PR c++/7053
	* g++.dg/template/friend20.C: New test.

Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.635.2.32
diff -c -5 -p -r1.635.2.32 pt.c
*** cp/pt.c	14 Jul 2003 05:18:06 -0000	1.635.2.32
--- cp/pt.c	14 Jul 2003 19:50:24 -0000
*************** static int inline_needs_template_parms P
*** 126,136 ****
  static void push_inline_template_parms_recursive PARAMS ((tree, int));
  static tree retrieve_specialization PARAMS ((tree, tree));
  static tree retrieve_local_specialization PARAMS ((tree));
  static tree register_specialization PARAMS ((tree, tree, tree));
  static void register_local_specialization PARAMS ((tree, tree));
! static int unregister_specialization PARAMS ((tree, tree));
  static tree reduce_template_parm_level PARAMS ((tree, tree, int));
  static tree build_template_decl PARAMS ((tree, tree));
  static int mark_template_parm PARAMS ((tree, void *));
  static int template_parm_this_level_p PARAMS ((tree, void *));
  static tree tsubst_friend_function PARAMS ((tree, tree));
--- 126,136 ----
  static void push_inline_template_parms_recursive PARAMS ((tree, int));
  static tree retrieve_specialization PARAMS ((tree, tree));
  static tree retrieve_local_specialization PARAMS ((tree));
  static tree register_specialization PARAMS ((tree, tree, tree));
  static void register_local_specialization PARAMS ((tree, tree));
! static int reregister_specialization PARAMS ((tree, tree, tree));
  static tree reduce_template_parm_level PARAMS ((tree, tree, int));
  static tree build_template_decl PARAMS ((tree, tree));
  static int mark_template_parm PARAMS ((tree, void *));
  static int template_parm_this_level_p PARAMS ((tree, void *));
  static tree tsubst_friend_function PARAMS ((tree, tree));
*************** register_specialization (spec, tmpl, arg
*** 1039,1064 ****
  
    return spec;
  }
  
  /* Unregister the specialization SPEC as a specialization of TMPL.
!    Returns nonzero if the SPEC was listed as a specialization of
!    TMPL.  */
  
  static int
! unregister_specialization (spec, tmpl)
!      tree spec;
!      tree tmpl;
  {
    tree* s;
  
    for (s = &DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
         *s != NULL_TREE;
         s = &TREE_CHAIN (*s))
      if (TREE_VALUE (*s) == spec)
        {
! 	*s = TREE_CHAIN (*s);
  	return 1;
        }
  
    return 0;
  }
--- 1039,1065 ----
  
    return spec;
  }
  
  /* Unregister the specialization SPEC as a specialization of TMPL.
!    Replace it with NEW_SPEC, if NEW_SPEC is non-NULL.  Returns true
!    if the SPEC was listed as a specialization of TMPL.  */
  
  static int
! reregister_specialization (tree spec, tree tmpl, tree new_spec)
  {
    tree* s;
  
    for (s = &DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
         *s != NULL_TREE;
         s = &TREE_CHAIN (*s))
      if (TREE_VALUE (*s) == spec)
        {
! 	if (!new_spec)
! 	  *s = TREE_CHAIN (*s);
! 	else
! 	  TREE_VALUE (*s) = new_spec;
  	return 1;
        }
  
    return 0;
  }
*************** tsubst_friend_function (decl, args)
*** 4995,5006 ****
  		 any, with the new template information pertaining to
  		 the declaration.  */
  	      DECL_TEMPLATE_INFO (old_decl) = new_friend_template_info;
  
  	      if (TREE_CODE (old_decl) != TEMPLATE_DECL)
! 		/* duplicate_decls will take care of this case.  */
! 		;
  	      else 
  		{
  		  tree t;
  		  tree new_friend_args;
  
--- 4996,5008 ----
  		 any, with the new template information pertaining to
  		 the declaration.  */
  	      DECL_TEMPLATE_INFO (old_decl) = new_friend_template_info;
  
  	      if (TREE_CODE (old_decl) != TEMPLATE_DECL)
! 		reregister_specialization (new_friend,
! 					   most_general_template (old_decl),
! 					   old_decl);
  	      else 
  		{
  		  tree t;
  		  tree new_friend_args;
  
*************** regenerate_decl_from_template (decl, tmp
*** 10106,10116 ****
       because if would only be registered there if it were a partial
       instantiation of a specialization, which it isn't: it's a full
       instantiation.  */
    gen_tmpl = most_general_template (tmpl);
    push_access_scope_real (gen_tmpl, args, DECL_CONTEXT (decl));
!   unregistered = unregister_specialization (decl, gen_tmpl);
  
    /* If the DECL was not unregistered then something peculiar is
       happening: we created a specialization but did not call
       register_specialization for it.  */
    my_friendly_assert (unregistered, 0);
--- 10108,10118 ----
       because if would only be registered there if it were a partial
       instantiation of a specialization, which it isn't: it's a full
       instantiation.  */
    gen_tmpl = most_general_template (tmpl);
    push_access_scope_real (gen_tmpl, args, DECL_CONTEXT (decl));
!   unregistered = reregister_specialization (decl, gen_tmpl, NULL_TREE);
  
    /* If the DECL was not unregistered then something peculiar is
       happening: we created a specialization but did not call
       register_specialization for it.  */
    my_friendly_assert (unregistered, 0);
Index: testsuite/g++.dg/template/friend20.C
===================================================================
RCS file: testsuite/g++.dg/template/friend20.C
diff -N testsuite/g++.dg/template/friend20.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/template/friend20.C	14 Jul 2003 19:50:24 -0000
***************
*** 0 ****
--- 1,15 ----
+ template <class T>
+ struct A
+ {
+   friend void bar(A<T> a) {}
+ };
+ 
+ void bar(A<int>);
+ 
+ int main()
+ {
+   A<int> a;
+ 
+   bar(a);
+ }
+ 


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