Blame SOURCES/gcc32-c++-reregister-specialization.patch

727081
2003-07-14  Mark Mitchell  <mark@codesourcery.com>
727081
727081
	PR c++/7053
727081
	* pt.c (unregister_specialization): Rename to ...
727081
	(reregister_specialization): ... this.
727081
	(tsubst_friend_function): Use it.
727081
	(regenerate_decl_from_template): Likewise.
727081
727081
	* g++.dg/template/friend20.C: New test.
727081
727081
--- gcc/cp/pt.c	14 Jul 2003 10:08:58 -0000	1.635.2.33
727081
+++ gcc/cp/pt.c	14 Jul 2003 20:18:18 -0000	1.635.2.34
727081
@@ -128,7 +128,7 @@ static tree retrieve_specialization PARA
727081
 static tree retrieve_local_specialization PARAMS ((tree));
727081
 static tree register_specialization PARAMS ((tree, tree, tree));
727081
 static void register_local_specialization PARAMS ((tree, tree));
727081
-static int unregister_specialization PARAMS ((tree, tree));
727081
+static int reregister_specialization PARAMS ((tree, tree, tree));
727081
 static tree reduce_template_parm_level PARAMS ((tree, tree, int));
727081
 static tree build_template_decl PARAMS ((tree, tree));
727081
 static int mark_template_parm PARAMS ((tree, void *));
727081
@@ -969,13 +969,11 @@ register_specialization (spec, tmpl, arg
727081
 }
727081
 
727081
 /* Unregister the specialization SPEC as a specialization of TMPL.
727081
-   Returns nonzero if the SPEC was listed as a specialization of
727081
-   TMPL.  */
727081
+   Replace it with NEW_SPEC, if NEW_SPEC is non-NULL.  Returns true
727081
+   if the SPEC was listed as a specialization of TMPL.  */
727081
 
727081
 static int
727081
-unregister_specialization (spec, tmpl)
727081
-     tree spec;
727081
-     tree tmpl;
727081
+reregister_specialization (tree spec, tree tmpl, tree new_spec)
727081
 {
727081
   tree* s;
727081
 
727081
@@ -984,7 +982,10 @@ unregister_specialization (spec, tmpl)
727081
        s = &TREE_CHAIN (*s))
727081
     if (TREE_VALUE (*s) == spec)
727081
       {
727081
-	*s = TREE_CHAIN (*s);
727081
+	if (!new_spec)
727081
+	  *s = TREE_CHAIN (*s);
727081
+	else
727081
+	  TREE_VALUE (*s) = new_spec;
727081
 	return 1;
727081
       }
727081
 
727081
@@ -4807,8 +4808,9 @@ tsubst_friend_function (decl, args)
727081
 	      DECL_TEMPLATE_INFO (old_decl) = new_friend_template_info;
727081
 
727081
 	      if (TREE_CODE (old_decl) != TEMPLATE_DECL)
727081
-		/* duplicate_decls will take care of this case.  */
727081
-		;
727081
+		reregister_specialization (new_friend,
727081
+					   most_general_template (old_decl),
727081
+					   old_decl);
727081
 	      else 
727081
 		{
727081
 		  tree t;
727081
@@ -9897,7 +9899,7 @@ regenerate_decl_from_template (decl, tmp
727081
      instantiation of a specialization, which it isn't: it's a full
727081
      instantiation.  */
727081
   gen_tmpl = most_general_template (tmpl);
727081
-  unregistered = unregister_specialization (decl, gen_tmpl);
727081
+  unregistered = reregister_specialization (decl, gen_tmpl, NULL_TREE);
727081
 
727081
   /* If the DECL was not unregistered then something peculiar is
727081
      happening: we created a specialization but did not call
727081
--- gcc/testsuite/g++.dg/template/friend20.C	2004-12-09 13:34:01.422415552 +0100
727081
+++ gcc/testsuite/g++.dg/template/friend20.C	2003-07-15 02:29:07.000000000 +0200
727081
@@ -0,0 +1,15 @@
727081
+template <class T>
727081
+struct A
727081
+{
727081
+  friend void bar(A<T> a) {}
727081
+};
727081
+
727081
+void bar(A<int>);
727081
+
727081
+int main()
727081
+{
727081
+  A<int> a;
727081
+
727081
+  bar(a);
727081
+}
727081
+