diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index fe0fbf7bbdc..84e61ca955c 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,13 @@ +2018-10-03 Jonathan Wakely + + PR libstdc++/59439 + * src/c++98/locale.cc (locale::locale(const locale&)): Bypass + reference count updates for the classic locale. + (locale::~locale()): Likewise. + (locale::operator=(const locale&)): Likewise. + * src/c++98/locale_init.cc (locale::locale()): Likewise. + (locale::global(const locale&)): Likewise. + 2018-10-03 François Dumont * include/debug/map.h diff --git a/libstdc++-v3/src/c++98/locale.cc b/libstdc++-v3/src/c++98/locale.cc index 148bf59658e..fe06d297039 100644 --- a/libstdc++-v3/src/c++98/locale.cc +++ b/libstdc++-v3/src/c++98/locale.cc @@ -77,7 +77,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION locale::locale(const locale& __other) throw() : _M_impl(__other._M_impl) - { _M_impl->_M_add_reference(); } + { + if (_M_impl != _S_classic) + _M_impl->_M_add_reference(); + } // This is used to initialize global and classic locales, and // assumes that the _Impl objects are constructed correctly. @@ -86,7 +89,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { } locale::~locale() throw() - { _M_impl->_M_remove_reference(); } + { + if (_M_impl != _S_classic) + _M_impl->_M_remove_reference(); + } bool locale::operator==(const locale& __rhs) const throw() @@ -112,8 +118,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const locale& locale::operator=(const locale& __other) throw() { - __other._M_impl->_M_add_reference(); - _M_impl->_M_remove_reference(); + if (__other._M_impl != _S_classic) + __other._M_impl->_M_add_reference(); + if (_M_impl != _S_classic) + _M_impl->_M_remove_reference(); _M_impl = __other._M_impl; return *this; } diff --git a/libstdc++-v3/src/c++98/locale_init.cc b/libstdc++-v3/src/c++98/locale_init.cc index c9078c015c3..b580a9f9d58 100644 --- a/libstdc++-v3/src/c++98/locale_init.cc +++ b/libstdc++-v3/src/c++98/locale_init.cc @@ -257,9 +257,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // fall back to lock protected access to both _S_global and // its reference count. _M_impl = _S_global; - if (_M_impl == _S_classic) - _M_impl->_M_add_reference(); - else + if (_M_impl != _S_classic) { __gnu_cxx::__scoped_lock sentry(get_locale_mutex()); _S_global->_M_add_reference(); @@ -275,7 +273,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { __gnu_cxx::__scoped_lock sentry(get_locale_mutex()); __old = _S_global; - __other._M_impl->_M_add_reference(); + if (__other._M_impl != _S_classic) + __other._M_impl->_M_add_reference(); _S_global = __other._M_impl; const string __other_name = __other.name(); if (__other_name != "*") @@ -284,7 +283,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Reference count sanity check: one reference removed for the // subsition of __other locale, one added by return-by-value. Net - // difference: zero. When the returned locale object's destrutor + // difference: zero. When the returned locale object's destructor // is called, then the reference count is decremented and possibly // destroyed. return locale(__old);