From 50bd32625723fb08ad55690c96697de72d8d936d Mon Sep 17 00:00:00 2001 From: mmitchel Date: Sat, 3 Dec 2005 01:02:33 +0000 Subject: [PATCH] PR c++/24173 * decl.c (duplicate_decls): Don't rely on DECL_TEMPLATE_INFO after clobbering newdecl. PR c++/24173 * g++.dg/template/friend40.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@107983 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/decl.c | 8 ++++++-- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/template/friend40.C | 16 ++++++++++++++++ 4 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/friend40.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1197d022554..b2b30097ac7 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2005-12-02 Mark Mitchell + + PR c++/24173 + * decl.c (duplicate_decls): Don't rely on DECL_TEMPLATE_INFO after + clobbering newdecl. + 2005-12-02 Richard Guenther * semantics.c (simplify_aggr_init_expr): Use buildN instead diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 71aac1a1717..ca2e221d0f4 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -1054,6 +1054,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) unsigned olddecl_uid = DECL_UID (olddecl); int olddecl_friend = 0, types_match = 0, hidden_friend = 0; int new_defines_function = 0; + tree new_template; if (newdecl == olddecl) return olddecl; @@ -1690,6 +1691,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) if (! DECL_EXTERNAL (olddecl)) DECL_EXTERNAL (newdecl) = 0; + new_template = NULL_TREE; if (DECL_LANG_SPECIFIC (newdecl) && DECL_LANG_SPECIFIC (olddecl)) { DECL_INTERFACE_KNOWN (newdecl) |= DECL_INTERFACE_KNOWN (olddecl); @@ -1712,6 +1714,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) DECL_LANG_SPECIFIC (olddecl)->decl_flags.u2; DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl); DECL_REPO_AVAILABLE_P (newdecl) = DECL_REPO_AVAILABLE_P (olddecl); + if (DECL_TEMPLATE_INFO (newdecl)) + new_template = DECL_TI_TEMPLATE (newdecl); DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl); DECL_INITIALIZED_IN_CLASS_P (newdecl) |= DECL_INITIALIZED_IN_CLASS_P (olddecl); @@ -1873,7 +1877,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) memcpy ((char *) olddecl + sizeof (struct tree_decl_common), (char *) newdecl + sizeof (struct tree_decl_common), sizeof (struct tree_function_decl) - sizeof (struct tree_decl_common)); - if (DECL_TEMPLATE_INFO (newdecl)) + if (new_template) /* If newdecl is a template instantiation, it is possible that the following sequence of events has occurred: @@ -1896,7 +1900,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) instantiations so that if we try to do the instantiation again we won't get the clobbered declaration. */ reregister_specialization (newdecl, - DECL_TI_TEMPLATE (newdecl), + new_template, olddecl); } else diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 41888c827e0..415cd85679c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-12-02 Mark Mitchell + + PR c++/24173 + * g++.dg/template/friend40.C: New test. + 2005-12-02 Jakub Jelinek PR target/25199 diff --git a/gcc/testsuite/g++.dg/template/friend40.C b/gcc/testsuite/g++.dg/template/friend40.C new file mode 100644 index 00000000000..39dd994e9d1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend40.C @@ -0,0 +1,16 @@ +// PR c++/24173 +// { dg-options "--param ggc-min-expand=0 --param ggc-min-heapsize=0" } + +template struct A; + +void foo(A<0>); + +template struct A +{ + friend void foo(A<0>); +}; + +void bar() +{ + foo(A<0>()); +} -- 2.11.0