diff --git a/libstdc++-v3/config/locale/gnu/c_locale.h b/libstdc++-v3/config/locale/gnu/c_locale.h index 176e022b85c..526b62215e1 100644 --- a/libstdc++-v3/config/locale/gnu/c_locale.h +++ b/libstdc++-v3/config/locale/gnu/c_locale.h @@ -61,6 +61,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef __locale_t __c_locale; +#if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT \ + && defined __LONG_DOUBLE_IEEE128__ +namespace __gnu_cxx_ieee128 { +#endif + // Convert numeric value of type double and long double to string and // return length of string. If vsnprintf is available use it, otherwise // fall back to the unsafe vsprintf which, in general, can be dangerous @@ -108,6 +113,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __ret; } +#if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT \ + && defined __LONG_DOUBLE_IEEE128__ +} // namespace __gnu_cxx_ieee128 +#endif + _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/config/os/gnu-linux/ldbl-ieee128-extra.ver b/libstdc++-v3/config/os/gnu-linux/ldbl-ieee128-extra.ver index 9b421b6f1f9..830cb8c40f4 100644 --- a/libstdc++-v3/config/os/gnu-linux/ldbl-ieee128-extra.ver +++ b/libstdc++-v3/config/os/gnu-linux/ldbl-ieee128-extra.ver @@ -2,7 +2,8 @@ GLIBCXX_IEEE128_3.4.29 { - *__gnu_cxx_ieee128*; + _Z*St17__gnu_cxx_ieee1287num_get*; + _Z*St17__gnu_cxx_ieee1287num_put*; _ZNSt14numeric_limitsIu9__ieee128E*; _ZNSirsERu9__ieee128; @@ -45,6 +46,10 @@ GLIBCXX_IEEE128_3.4.29 { } GLIBCXX_3.4.29; +GLIBCXX_IEEE128_3.4.30 { + _ZNSt17__gnu_cxx_ieee12816__convert_from_vERKP15__locale_structPciPKcz; +} GLIBCXX_3.4.30; + CXXABI_IEEE128_1.3.13 { _ZT[IS]u9__ieee128; diff --git a/libstdc++-v3/include/bits/locale_facets_nonio.tcc b/libstdc++-v3/include/bits/locale_facets_nonio.tcc index 64737823374..98442418f51 100644 --- a/libstdc++-v3/include/bits/locale_facets_nonio.tcc +++ b/libstdc++-v3/include/bits/locale_facets_nonio.tcc @@ -635,6 +635,9 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 #if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT \ && defined __LONG_DOUBLE_IEEE128__ +extern "C" +__typeof__(__builtin_snprintf) __glibcxx_snprintfibm128 __asm__("snprintf"); + template _OutIter money_put<_CharT, _OutIter>:: @@ -643,30 +646,24 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11 { const locale __loc = __io.getloc(); const ctype<_CharT>& __ctype = use_facet >(__loc); -#if _GLIBCXX_USE_C99_STDIO // First try a buffer perhaps big enough. int __cs_size = 64; char* __cs = static_cast(__builtin_alloca(__cs_size)); + const __c_locale __old = __gnu_cxx::__uselocale(_S_get_c_locale()); + // _GLIBCXX_RESOLVE_LIB_DEFECTS // 328. Bad sprintf format modifier in money_put<>::do_put() - int __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, - "%.*Lf", 0, __units); + int __len = __glibcxx_snprintfibm128(__cs, __cs_size, "%.*Lf", 0, + __units); // If the buffer was not large enough, try again with the correct size. if (__len >= __cs_size) { __cs_size = __len + 1; __cs = static_cast(__builtin_alloca(__cs_size)); - __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, - "%.*Lf", 0, __units); + __len = __glibcxx_snprintfibm128(__cs, __cs_size, "%.*Lf", 0, + __units); } -#else - // max_exponent10 + 1 for the integer part, + 2 for sign and '\0'. - const int __cs_size = - __gnu_cxx::__numeric_traits::__max_exponent10 + 3; - char* __cs = static_cast(__builtin_alloca(__cs_size)); - int __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, "%.*Lf", - 0, __units); -#endif + __gnu_cxx::__uselocale(__old); string_type __digits(__len, char_type()); __ctype.widen(__cs, __cs + __len, &__digits[0]); return __intl ? _M_insert(__s, __io, __fill, __digits) diff --git a/libstdc++-v3/testsuite/util/testsuite_abi.cc b/libstdc++-v3/testsuite/util/testsuite_abi.cc index 0ac0ea3fa90..3dee737b2e5 100644 --- a/libstdc++-v3/testsuite/util/testsuite_abi.cc +++ b/libstdc++-v3/testsuite/util/testsuite_abi.cc @@ -213,6 +213,7 @@ check_version(symbol& test, bool added) known_versions.push_back("GLIBCXX_3.4.30"); known_versions.push_back("GLIBCXX_LDBL_3.4.29"); known_versions.push_back("GLIBCXX_IEEE128_3.4.29"); + known_versions.push_back("GLIBCXX_IEEE128_3.4.30"); known_versions.push_back("CXXABI_1.3"); known_versions.push_back("CXXABI_LDBL_1.3"); known_versions.push_back("CXXABI_1.3.1"); @@ -247,11 +248,8 @@ check_version(symbol& test, bool added) // Check that added symbols are added in the latest pre-release version. bool latestp = (test.version_name == "GLIBCXX_3.4.30" - // XXX remove next 3 lines when baselines have been regenerated - // to include {IEEE128,LDBL} symbols: - || test.version_name == "GLIBCXX_LDBL_3.4.29" - || test.version_name == "GLIBCXX_IEEE128_3.4.29" - || test.version_name == "CXXABI_IEEE128_1.3.13" + // XXX remove next line when baselines have been regenerated. + || test.version_name == "GLIBCXX_IEEE128_3.4.30" || test.version_name == "CXXABI_1.3.13" || test.version_name == "CXXABI_FLOAT128" || test.version_name == "CXXABI_TM_1");