|
|
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 |
+
|