While checking how to fix

PR libstdc++-v3/1773    __cplusplus defined to 1, should be 199711L

it was discovered that without countermeasures, changing __cplusplus
from 1 to 199711L breaks the Solaris ABI by moving tm from the global
namespace to std, among others, e.g.

-FUNC:std::__timepunct<char>::_M_put(char*, unsigned long, char const*, tm 
const*) const@@GLIBCXX_3.4
+FUNC:std::__timepunct<char>::_M_put(char*, unsigned long, char const*, std::tm 
const*) const@@GLIBCXX_3.4
-FUNC:std::__timepunct<wchar_t>::_M_put(wchar_t*, unsigned long, wchar_t 
const*, tm const*) const@@GLIBCXX_3.4
+FUNC:std::__timepunct<wchar_t>::_M_put(wchar_t*, unsigned long, wchar_t 
const*, std::tm const*) const@@GLIBCXX_3.4

This patch (entirely Marc's work, I've only added the ChangeLog entry
and fixed some formatting issues) avoids that.

Together with the companion patches (already posted or in the process of
being so), it allowed successful i386-pc-solaris2.{8, 9, 10, 11}
bootstraps without regressions.

I have no idea if the approach is right, but something needs to be done
here.

Comments?

        Rainer


2011-08-07  Marc Glisse  <marc.gli...@normalesup.org>

        PR libstdc++-v3/1773
        * mangle.c (substitution_identifier_index_t): Define SUBID_TM,
        SUBID_DIV_T, SUBID_LDIV_T, SUBID_LCONV.
        (is_std_substitution2): New function.
        (write_unscoped_name): Don't emit tm, div_t, ldiv_t, lconv in ::std.
        (init_mangle): Cache tm, div_t, ldiv_t, lconv identifies.

diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -127,6 +127,10 @@ typedef enum
   SUBID_BASIC_ISTREAM,
   SUBID_BASIC_OSTREAM,
   SUBID_BASIC_IOSTREAM,
+  SUBID_TM,
+  SUBID_DIV_T,
+  SUBID_LDIV_T,
+  SUBID_LCONV,
   SUBID_MAX
 }
 substitution_identifier_index_t;
@@ -163,6 +167,8 @@ static inline tree canonicalize_for_subs
 static void add_substitution (tree);
 static inline int is_std_substitution (const tree,
                                       const substitution_identifier_index_t);
+static inline int is_std_substitution2 (const tree,
+                                       const substitution_identifier_index_t);
 static inline int is_std_substitution_char (const tree,
                                            const 
substitution_identifier_index_t);
 static int find_substitution (tree);
@@ -437,6 +443,33 @@ is_std_substitution (const tree node,
              == subst_identifiers[index]));
 }
 
+static inline int
+is_std_substitution2 (const tree node,
+                     const substitution_identifier_index_t index)
+{
+  tree type = NULL;
+  tree decl = NULL;
+
+  if (DECL_P (node))
+    {
+      type = TREE_TYPE (node);
+      decl = node;
+    }
+  else if (CLASS_TYPE_P (node))
+    {
+      type = node;
+      decl = TYPE_NAME (node);
+    }
+  else
+    /* These are not the droids you're looking for.  */
+    return 0;
+
+  return (DECL_NAMESPACE_STD_P (CP_DECL_CONTEXT (decl))
+         && TYPE_LANG_SPECIFIC (type)
+         && (DECL_NAME (decl) == subst_identifiers[index]));
+}
+
+
 /* Helper function for find_substitution.  Returns nonzero if NODE,
    which may be a decl or a CLASS_TYPE, is the template-id
    ::std::identifier<char>, where identifier is
@@ -864,6 +897,10 @@ write_unscoped_name (const tree decl)
   /* Is DECL in ::std?  */
   if (DECL_NAMESPACE_STD_P (context))
     {
+      if (!is_std_substitution2 (decl, SUBID_TM)
+         && !is_std_substitution2 (decl, SUBID_DIV_T)
+         && !is_std_substitution2 (decl, SUBID_LDIV_T)
+         && !is_std_substitution2 (decl, SUBID_LCONV))
       write_string ("St");
       write_unqualified_name (decl);
     }
@@ -3095,6 +3132,10 @@ init_mangle (void)
   subst_identifiers[SUBID_BASIC_ISTREAM] = get_identifier ("basic_istream");
   subst_identifiers[SUBID_BASIC_OSTREAM] = get_identifier ("basic_ostream");
   subst_identifiers[SUBID_BASIC_IOSTREAM] = get_identifier ("basic_iostream");
+  subst_identifiers[SUBID_TM] = get_identifier ("tm");
+  subst_identifiers[SUBID_DIV_T] = get_identifier ("div_t");
+  subst_identifiers[SUBID_LDIV_T] = get_identifier ("ldiv_t");
+  subst_identifiers[SUBID_LCONV] = get_identifier ("lconv");
 }
 
 /* Generate the mangled name of DECL.  */

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University

Reply via email to