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