This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: PR 7053
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 14 Jul 2003 13:27:52 -0700
- Subject: C++ PATCH: PR 7053
- Reply-to: mark at codesourcery dot com
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);
+ }
+