On 09/10/19 16:59 +0100, Jonathan Wakely wrote:
If two threads see _M_index==0 concurrently they will both try to set
it, potentially storing the facet at two different indices in the array.
Either set the _M_index data member using an atomic compare-exchange
operation or while holding a mutex.
Also move the LONG_DOUBLE_COMPAT code into a separate function to remove
the visual noise it creates.
PR libstdc++/91057
* src/c++98/locale.cc (locale::id::_M_id()) [__GTHREADS]: Use atomic
compare-exchange or double-checked lock to ensure only one thread sets
the _M_index variable.
[_GLIBCXX_LONG_DOUBLE_COMPAT]: Call find_ldbl_sync_facet to detect
facets that share another facet's ID.
[_GLIBCXX_LONG_DOUBLE_COMPAT] (find_ldbl_sync_facet): New function.
Tested x86_64-linux, committed to trunk.
That patch was broken on powerpc and other targets with long double
compat symbols.
Tested powerpc64le-linux, committed to trunk.
commit 0964424db7ff62b3b1f561af60b1cc6560b4a742
Author: Jonathan Wakely <jwak...@redhat.com>
Date: Thu Oct 10 16:42:08 2019 +0100
PR libstdc++/91057 fix bootstrap failure on powerpc
PR libstdc++/91057
* src/c++98/locale.cc [_GLIBCXX_LONG_DOUBLE_COMPAT]
(find_ldbl_sync_facet): Fix parameter type and missing return.
diff --git a/libstdc++-v3/src/c++98/locale.cc b/libstdc++-v3/src/c++98/locale.cc
index 1d00edc6f51..74a800c9c15 100644
--- a/libstdc++-v3/src/c++98/locale.cc
+++ b/libstdc++-v3/src/c++98/locale.cc
@@ -478,7 +478,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#ifdef _GLIBCXX_LONG_DOUBLE_COMPAT
namespace {
inline locale::id*
- find_ldbl_sync_facet(locale::id* __idp)
+ find_ldbl_sync_facet(const locale::id* __idp)
{
# define _GLIBCXX_SYNC_ID(facet, mangled) \
if (__idp == &::mangled) \
@@ -494,6 +494,7 @@ namespace {
_GLIBCXX_SYNC_ID (money_get<wchar_t>, _ZNSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE);
_GLIBCXX_SYNC_ID (money_put<wchar_t>, _ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE);
# endif
+ return 0;
}
} // namespace
#endif