On the platform that add underscore before the external symbol, the name
mangling in the following code generates different name for
"testtemplate<int>::memberfunc()::memberfunclocalstaticvar const" with and
without -O3. With -O3, the mangled name is incorrect.
--<testinc.hxx>--
extern void func();

class testclass0
{
public:
        testclass0();
        ~testclass0();
private:
        int testvar;
};

template< class testtemplatedummyparamclass >
class testtemplate
{
    public :
        testtemplate()
        {
            memberfunc();
        }

        ~testtemplate()
        {
            memberfunc();
        }


    private :

        testclass0& memberfunc() const
        {
            static testclass0 memberfunclocalstaticvar;
            return memberfunclocalstaticvar;
        }
};

--<test1>--
#include "testinc.hxx"

testtemplate< int > globalval;

extern "C"
{
int main()
{
  func();
  return 0;
}
}
---
Moreover, the following code always generates wrong mangled name, with or
without -O3.

--<test2.cxx>--
#include "testinc.hxx"

testclass0::testclass0()
{
        testvar=1;
}

testclass0::~testclass0()
{
}

void func()
{
        static testtemplate< int > funclocalstaticval;
}

---

If we link the object together, one of the sections for member function static
variable will be discarded and either one of the reference will not be
resolved. This will cause program crash.

The behavior seems to be caused by the check in make_rtl_for_local_static in
gcc/c-semantics fails if the name is mangled for C++ and the underscore is
added in front.

If we have a flag that indicates if the underscore is added, it is easy to
solve the problem but we do not have it. The following patch will remedy the
problem by mangling the name again and compare.

--<mismangle.patch>--
--- gcc/c-semantics.c.orig      2004-08-28 16:20:48.000000000 +0900
+++ gcc/c-semantics.c   2005-08-07 18:13:46.000000000 +0900
@@ -231,6 +231,7 @@
 make_rtl_for_local_static (tree decl)
 {
   const char *asmspec = NULL;
+  char *temp;

   /* If we inlined this variable, we could see it's declaration
      again.  */
@@ -253,9 +254,19 @@
      may as well not pass it in.  If there isn't RTL, then we didn't
      already create RTL, which means that the modification to
      DECL_ASSEMBLER_NAME came only via the explicit extension.  */
+  
   if (DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl)
       && !DECL_RTL_SET_P (decl))
-    asmspec = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+    {
+      temp = alloca(strlen(IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME
(decl)))+1);
+      strcpy(temp, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
+      change_decl_assembler_name(decl, NULL_TREE);
+      if (strcmp(IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), temp)!=0)
+         {
+           change_decl_assembler_name(decl, get_identifier(temp));
+           asmspec = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+         }
+    }

   rest_of_decl_compilation (decl, asmspec, /*top_level=*/0, /*at_end=*/0);
 }
--- gcc/cgraph.c.orig   2004-06-06 11:09:54.000000000 +0900
+++ gcc/cgraph.c        2005-08-07 17:59:16.000000000 +0900
@@ -523,6 +523,8 @@
         vnode = NULL;
     }
   SET_DECL_ASSEMBLER_NAME (decl, name);
+  if (name != NULL_TREE)
+    {
   if (node)
     {
       slot = 
@@ -541,6 +543,7 @@
        abort ();
       *slot = vnode;
     }
+    }
 }

 /* Try to find existing function for identifier ID.  */


-- 
           Summary: Name Mangling Problem
           Product: gcc
           Version: 3.4.2
            Status: UNCONFIRMED
          Severity: critical
          Priority: P3
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: t_ono at hkfreak dot net


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26013

Reply via email to