From bb5ecf29592e396bce6f8b793430d094d65c5309 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Wed, 15 Sep 2004 03:22:19 +0000 Subject: [PATCH] re PR c++/17324 (Error: symbol `bRKNS0_IT_SD_EE' is already defined) PR c++/17324 * mangle.c (partially_mangled_name): New variable. (partially_mangled_name_len): Likewise. (save_partially_mangled_name): New function. (restore_partially_mangled_name): Likewise. (write_encoding): Save and restore partially mangled names around calls to get_mostly_instantiated_function_type. (write_unqualified_name): Likewise. PR c++/17324 * g++.dg/template/mangle1.C: New test. From-SVN: r87530 --- gcc/cp/ChangeLog | 11 +++++ gcc/cp/mangle.c | 54 +++++++++++++++++++++++-- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/g++.dg/template/mangle1.C | 16 ++++++++ 4 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/mangle1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a54f556869a..e623148e275 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2004-09-14 Mark Mitchell + + PR c++/17324 + * mangle.c (partially_mangled_name): New variable. + (partially_mangled_name_len): Likewise. + (save_partially_mangled_name): New function. + (restore_partially_mangled_name): Likewise. + (write_encoding): Save and restore partially mangled names around + calls to get_mostly_instantiated_function_type. + (write_unqualified_name): Likewise. + 2004-09-14 Nathan Sidwell * pt.c (unify): Replace gcc_unreachable with gcc_assert. diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index a3d885a4aac..41c381d45c1 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -115,10 +115,17 @@ static struct obstack *mangle_obstack; be IDENTIFIER_NODEs. */ static struct obstack name_obstack; - /* The first object on the name_obstack; we use this to free memory - allocated on the name_obstack. */ +/* The first object on the name_obstack; we use this to free memory + allocated on the name_obstack. */ static void *name_base; +/* An incomplete mangled name. There will be no NUL terminator. If + there is no incomplete mangled name, this variable is NULL. */ +static char *partially_mangled_name; + +/* The number of characters in the PARTIALLY_MANGLED_NAME. */ +static size_t partially_mangled_name_len; + /* Indices into subst_identifiers. These are identifiers used in special substitution rules. */ typedef enum @@ -254,6 +261,42 @@ static void write_java_integer_type_codes (const tree); #define write_unsigned_number(NUMBER) \ write_number ((NUMBER), /*unsigned_p=*/1, 10) +/* Save the current (incomplete) mangled name and release the obstack + storage holding it. This function should be used during mangling + when making a call that could result in a call to get_identifier, + as such a call will clobber the same obstack being used for + mangling. This function may not be called twice without an + intervening call to restore_partially_mangled_name. */ + +static void +save_partially_mangled_name (void) +{ + if (mangle_obstack == &ident_hash->stack) + { + gcc_assert (!partially_mangled_name); + partially_mangled_name_len = obstack_object_size (mangle_obstack); + partially_mangled_name = xmalloc (partially_mangled_name_len); + memcpy (partially_mangled_name, obstack_base (mangle_obstack), + partially_mangled_name_len); + obstack_free (mangle_obstack, obstack_finish (mangle_obstack)); + } +} + +/* Restore the incomplete mangled name saved with + save_partially_mangled_name. */ + +static void +restore_partially_mangled_name (void) +{ + if (partially_mangled_name) + { + obstack_grow (mangle_obstack, partially_mangled_name, + partially_mangled_name_len); + free (partially_mangled_name); + partially_mangled_name = NULL; + } +} + /* If DECL is a template instance, return nonzero and, if TEMPLATE_INFO is non-NULL, set *TEMPLATE_INFO to its template info. Otherwise return zero. */ @@ -702,7 +745,9 @@ write_encoding (const tree decl) if (decl_is_template_id (decl, NULL)) { + save_partially_mangled_name (); fn_type = get_mostly_instantiated_function_type (decl); + restore_partially_mangled_name (); /* FN_TYPE will not have parameter types for in-charge or VTT parameters. Therefore, we pass NULL_TREE to write_bare_function_type -- otherwise, it will get @@ -1063,7 +1108,10 @@ write_unqualified_name (const tree decl) tree type; if (decl_is_template_id (decl, NULL)) { - tree fn_type = get_mostly_instantiated_function_type (decl); + tree fn_type; + save_partially_mangled_name (); + fn_type = get_mostly_instantiated_function_type (decl); + restore_partially_mangled_name (); type = TREE_TYPE (fn_type); } else diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 61744bf33f7..3f28435ffff 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-09-14 Mark Mitchell + + PR c++/17324 + * g++.dg/template/mangle1.C: New test. + 2004-09-14 Diego Novillo PR tree-optimization/17252 diff --git a/gcc/testsuite/g++.dg/template/mangle1.C b/gcc/testsuite/g++.dg/template/mangle1.C new file mode 100644 index 00000000000..96d06472341 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/mangle1.C @@ -0,0 +1,16 @@ +// PR c++/17324 +// { dg-do assemble } + +template struct A +{ + template void foo(const A&) {} +}; + +template struct B +{ + template void bar(const A&); + void baz() { A<0,B>().foo(A<0,B>()); } +}; + +template struct B; +template struct B; -- 2.30.2