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