re PR c++/17324 (Error: symbol `bRKNS0_IT_SD_EE' is already defined)
authorMark Mitchell <mark@codesourcery.com>
Wed, 15 Sep 2004 03:22:19 +0000 (03:22 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Wed, 15 Sep 2004 03:22:19 +0000 (03:22 +0000)
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
gcc/cp/mangle.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/mangle1.C [new file with mode: 0644]

index a54f556869a8094f2827c447db3b56b9d6d48a13..e623148e275ef8922926becd55db77bd9e88ced6 100644 (file)
@@ -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.
index a3d885a4aacc870f684f784bdbf3d1e9c97dd69d..41c381d45c1d99fa3bc76b531dad00592fe0a10a 100644 (file)
@@ -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
index 61744bf33f7e11109b5aef8dd25217b3b665b5e9..3f28435ffff58426e6ce5d276d1c86d2ae9c5923 100644 (file)
@@ -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 (file)
index 0000000..96d0647
--- /dev/null
@@ -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>;