aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2004-09-15 03:22:19 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2004-09-15 03:22:19 +0000
commitbb5ecf29592e396bce6f8b793430d094d65c5309 (patch)
tree6e613c96b5981e4ad2d16f09f4f2e2c54a8bfdd4 /gcc
parent391f9afbd2d6ac8dd691c6d79a8817c63a637ca8 (diff)
downloadgcc-bb5ecf29592e396bce6f8b793430d094d65c5309.zip
gcc-bb5ecf29592e396bce6f8b793430d094d65c5309.tar.gz
gcc-bb5ecf29592e396bce6f8b793430d094d65c5309.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog11
-rw-r--r--gcc/cp/mangle.c54
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/template/mangle1.C16
4 files changed, 83 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index a54f556..e623148 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,14 @@
+2004-09-14 Mark Mitchell <mark@codesourcery.com>
+
+ 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 <nathan@codesourcery.com>
* pt.c (unify): Replace gcc_unreachable with gcc_assert.
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index a3d885a..41c381d 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 61744bf..3f28435 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2004-09-14 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/17324
+ * g++.dg/template/mangle1.C: New test.
+
2004-09-14 Diego Novillo <dnovillo@redhat.com>
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 0000000..96d0647
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/mangle1.C
@@ -0,0 +1,16 @@
+// PR c++/17324
+// { dg-do assemble }
+
+template<int, typename T> struct A
+{
+ template<int I> void foo(const A<I,T>&) {}
+};
+
+template<typename> struct B
+{
+ template<int J> void bar(const A<J,B>&);
+ void baz() { A<0,B>().foo(A<0,B>()); }
+};
+
+template struct B<void>;
+template struct B<int>;