aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libstdc++-v3/include/bits/locale_classes.tcc13
-rw-r--r--libstdc++-v3/src/c++11/localename.cc4
-rw-r--r--libstdc++-v3/src/c++98/locale.cc2
-rw-r--r--libstdc++-v3/testsuite/22_locale/locale/cons/names.cc61
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();
+}