diff options
-rw-r--r-- | libstdc++-v3/include/bits/locale_classes.tcc | 13 | ||||
-rw-r--r-- | libstdc++-v3/src/c++11/localename.cc | 4 | ||||
-rw-r--r-- | libstdc++-v3/src/c++98/locale.cc | 2 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/22_locale/locale/cons/names.cc | 61 |
4 files changed, 77 insertions, 3 deletions
diff --git a/libstdc++-v3/include/bits/locale_classes.tcc b/libstdc++-v3/include/bits/locale_classes.tcc index 6309758..00eeb7d 100644 --- a/libstdc++-v3/include/bits/locale_classes.tcc +++ b/libstdc++-v3/include/bits/locale_classes.tcc @@ -44,6 +44,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION locale:: locale(const locale& __other, _Facet* __f) { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2295. Locale name when the provided Facet is a nullptr + if (__builtin_expect(!__f, 0)) + { + _M_impl = __other._M_impl; + _M_impl->_M_add_reference(); + return; + } + _M_impl = new _Impl(*__other._M_impl, 1); __try @@ -72,6 +81,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __tmp->_M_remove_reference(); __throw_exception_again; } + delete[] __tmp->_M_names[0]; + __tmp->_M_names[0] = 0; // Unnamed. return locale(__tmp); } @@ -163,7 +174,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ template<typename _Facet> inline bool - has_facet(const locale& __loc) throw() + has_facet(const locale& __loc) _GLIBCXX_USE_NOEXCEPT { #if __cplusplus >= 201103L static_assert(__is_base_of(locale::facet, _Facet), diff --git a/libstdc++-v3/src/c++11/localename.cc b/libstdc++-v3/src/c++11/localename.cc index cde94ec..909cf4c 100644 --- a/libstdc++-v3/src/c++11/localename.cc +++ b/libstdc++-v3/src/c++11/localename.cc @@ -326,7 +326,9 @@ const int num_facets = ( _M_replace_categories(const _Impl* __imp, category __cat) { category __mask = 1; - if (!_M_names[0] || !__imp->_M_names[0]) + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3676. Name of locale composed using std::locale::none + if (!_M_names[0] || (__cat != none && !__imp->_M_names[0])) { if (_M_names[0]) { diff --git a/libstdc++-v3/src/c++98/locale.cc b/libstdc++-v3/src/c++98/locale.cc index 3749408..0e7533e 100644 --- a/libstdc++-v3/src/c++98/locale.cc +++ b/libstdc++-v3/src/c++98/locale.cc @@ -323,7 +323,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION locale::_Impl:: _M_install_facet(const locale::id* __idp, const facet* __fp) { - if (__fp) + if (__builtin_expect(__fp != 0, 1)) { size_t __index = __idp->_M_id(); diff --git a/libstdc++-v3/testsuite/22_locale/locale/cons/names.cc b/libstdc++-v3/testsuite/22_locale/locale/cons/names.cc new file mode 100644 index 0000000..2a9cfe4 --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/locale/cons/names.cc @@ -0,0 +1,61 @@ +// { dg-do run } + +#include <locale> +#include <testsuite_hooks.h> + +void +test_pr108323() +{ + std::locale named = std::locale::classic(); + std::locale unnamed = named.combine<std::ctype<char> >(named); + + // Bug libstdc++/108323 - combine does not change the locale name + VERIFY( unnamed.name() == "*" ); +} + +void +test_lwg2295() +{ + std::locale named = std::locale::classic(); + std::locale unnamed(named, &std::use_facet<std::ctype<char> >(named)); + VERIFY( unnamed.name() == "*" ); + + // LWG 2295. Locale name when the provided Facet is a nullptr + std::locale loc(named, (std::ctype<char>*)0); + VERIFY( loc.name() != "*" ); + VERIFY( loc.name() == named.name() ); +} + +void +test_lwg3676() +{ + std::locale named = std::locale::classic(); + std::locale unnamed = named.combine<std::ctype<char> >(named); + std::locale combo; + + // LWG 3676. Name of locale composed using std::locale::none + + combo = std::locale(named, named, std::locale::numeric); + VERIFY( combo.name() != "*" ); + combo = std::locale(named, named, std::locale::none); + VERIFY( combo.name() != "*" ); + combo = std::locale(named, unnamed, std::locale::numeric); + VERIFY( combo.name() == "*" ); + combo = std::locale(named, unnamed, std::locale::none); + VERIFY( combo.name() != "*" ); + combo = std::locale(unnamed, named, std::locale::numeric); + VERIFY( combo.name() == "*" ); + combo = std::locale(unnamed, named, std::locale::none); + VERIFY( combo.name() == "*" ); + combo = std::locale(unnamed, unnamed, std::locale::numeric); + VERIFY( combo.name() == "*" ); + combo = std::locale(unnamed, unnamed, std::locale::none); + VERIFY( combo.name() == "*" ); +} + +int main() +{ + test_pr108323(); + test_lwg2295(); + test_lwg3676(); +} |