diff options
author | Mark Mitchell <mark@codesourcery.com> | 2005-12-03 01:02:33 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2005-12-03 01:02:33 +0000 |
commit | 50b56799f728d43ffa0fc941bf6757908bc76f46 (patch) | |
tree | 490c2963de08fb5bab58a5be8baff8aaef7160b7 /gcc/cp/decl.c | |
parent | 0889ab4a1a25a1a4e16ba5c09142acf8ace42a76 (diff) | |
download | gcc-50b56799f728d43ffa0fc941bf6757908bc76f46.zip gcc-50b56799f728d43ffa0fc941bf6757908bc76f46.tar.gz gcc-50b56799f728d43ffa0fc941bf6757908bc76f46.tar.bz2 |
re PR c++/24173 (ICE with garbage collection)
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.
From-SVN: r107983
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r-- | gcc/cp/decl.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 71aac1a..ca2e221 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 |