Reduce code instantiated by filesystem::path::_S_convert_loc
authorJonathan Wakely <jwakely@redhat.com>
Fri, 26 Apr 2019 14:04:45 +0000 (15:04 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Fri, 26 Apr 2019 14:04:45 +0000 (15:04 +0100)
Jakub noted in https://gcc.gnu.org/ml/libstdc++/2019-04/msg00140.html
that an unwanted std::wstring::_M_replace_dispatch symbol has started to
be exported from the Fedora shared library. This symbol is triggered by
the instantiation of std::wstring::assign(const char*, const char*) from
std::__str_codecvt_in which is called from path::_S_convert_loc. The
branch that triggers that instantiation can't actually happen in that
case, because codecvt facets will only return noconv when the input and
output types are the same. Guarding the assign call with an if-constexpr
check that the types are the same avoids instantiating template
specializations that will never actually be needed.

* config/abi/pre/gnu.ver (GLIBCXX_3.4): Replace wildcard that matches
wstring::_M_replace_dispatch with more specific patterns.
* include/bits/fs_path.h (path::_S_convert_loc<_InputIterator>):
Create const std::string to avoid redundant call to _S_convert_loc
with non-const pointers.
* include/bits/locale_conv.h (__do_str_codecvt): Use if-constexpr to
avoid unnecessary basic_string::assign instantiations.

From-SVN: r270602

libstdc++-v3/ChangeLog
libstdc++-v3/config/abi/pre/gnu.ver
libstdc++-v3/include/bits/fs_path.h
libstdc++-v3/include/bits/locale_conv.h

index d2f8ed4f1aa81a67a36d21afe2556260a192fe59..61841e87ce824e661e95533c068fcd4835892b75 100644 (file)
@@ -1,5 +1,13 @@
 2019-04-26  Jonathan Wakely  <jwakely@redhat.com>
 
+       * config/abi/pre/gnu.ver (GLIBCXX_3.4): Replace wildcard that matches
+       wstring::_M_replace_dispatch with more specific patterns.
+       * include/bits/fs_path.h (path::_S_convert_loc<_InputIterator>):
+       Create const std::string to avoid redundant call to _S_convert_loc
+       with non-const pointers.
+       * include/bits/locale_conv.h (__do_str_codecvt): Use if-constexpr to
+       avoid unnecessary basic_string::assign instantiations.
+
        * include/std/memory (__uses_alloc_args): Add string-literal to
        static_assert, to match the one in __uses_alloc.
        [__cpp_concepts] (_Std_pair): Use C++2a syntax for concept.
index e8cf6f0a4a9d272083a323b26f6222b4d0ef2407..7eff4e983f3fd4e84542bc81da42b3a2c3f04bb0 100644 (file)
@@ -299,7 +299,8 @@ GLIBCXX_3.4 {
     _ZNSbIwSt11char_traitsIwESaIwEE12_S_constructE[jmy]wRKS1_;
     _ZNSbIwSt11char_traitsIwESaIwEE12_S_empty_repEv;
     _ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_chars*;
-    _ZNSbIwSt11char_traitsIwESaIwEE[0-9][0-9]_M_replace*;
+    _ZNSbIwSt11char_traitsIwESaIwEE14_M_replace_aux*;
+    _ZNSbIwSt11char_traitsIwESaIwEE15_M_replace_safe*;
     _ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_destroy*;
     _ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_dispose*;
     _ZNSbIwSt11char_traitsIwESaIwEE4_Rep10_M_refcopyEv;
index 3674b4391f808a6888ece5145f4a5b9a1617b381..28878c627a7c191cd1d2f80ada661bb1be4fa5be 100644 (file)
@@ -539,7 +539,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
       _S_convert_loc(_InputIterator __src, __null_terminated,
                     const std::locale& __loc)
       {
-       std::string __s = _S_string_from_iter(__src);
+       const std::string __s = _S_string_from_iter(__src);
        return _S_convert_loc(__s.data(), __s.data() + __s.size(), __loc);
       }
 
index d7510dff80e4c5f8d156d54dbf8c76f4349c7ac1..4cb9c39ebb46c8d36362079edd9e2a5d5bda461d 100644 (file)
@@ -88,8 +88,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       if (__result == codecvt_base::noconv)
        {
-         __outstr.assign(__first, __last);
-         __count = __last - __first;
+         // The codecvt facet will only return noconv when the types are
+         // the same, so avoid instantiating basic_string::assign otherwise
+         if _GLIBCXX17_CONSTEXPR (is_same<typename _Codecvt::intern_type,
+                                          typename _Codecvt::extern_type>())
+           {
+             __outstr.assign(__first, __last);
+             __count = __last - __first;
+           }
        }
       else
        {