libstdc++: Define function to throw filesystem_error [PR 98471]
authorJonathan Wakely <jwakely@redhat.com>
Thu, 14 Jan 2021 14:26:19 +0000 (14:26 +0000)
committerJonathan Wakely <jwakely@redhat.com>
Thu, 14 Jan 2021 16:26:30 +0000 (16:26 +0000)
Fix ordering problem on Windows targets where filesystem_error was used
before being defined.

libstdc++-v3/ChangeLog:

PR libstdc++/98471
* include/bits/fs_path.h (__throw_conversion_error): New
function to throw or abort on character conversion errors.
(__wstr_from_utf8): Move definition after filesystem_error has
been defined. Use __throw_conversion_error.
(path::_S_convert<_EcharT>): Use __throw_conversion_error.
(path::_S_str_convert<_CharT, _Traits, _Allocator>): Likewise.
(path::u8string): Likewise.

libstdc++-v3/include/bits/fs_path.h

index 2897134c4c12bc6cfa0a95f74d16ab7ee159ff2c..1645c53cf5375cb50cb702d689f588b6c04b2ced 100644 (file)
@@ -238,24 +238,6 @@ namespace __detail
        return basic_string<_EcharT>(__first, __last);
     }
 
-#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
-  template<typename _Tp>
-    inline std::wstring
-    __wstr_from_utf8(const _Tp& __str)
-    {
-      static_assert(std::is_same_v<typename _Tp::value_type, char>);
-      std::wstring __wstr;
-      // XXX This assumes native wide encoding is UTF-16.
-      std::codecvt_utf8_utf16<wchar_t> __wcvt;
-      const auto __p = __str.data();
-      if (!__str_codecvt_in_all(__p, __p + __str.size(), __wstr, __wcvt))
-       _GLIBCXX_THROW_OR_ABORT(filesystem_error(
-             "Cannot convert character sequence",
-             std::make_error_code(errc::illegal_byte_sequence)));
-      return __wstr;
-    }
-#endif
-
 } // namespace __detail
   /// @endcond
 
@@ -743,6 +725,37 @@ namespace __detail
     std::__shared_ptr<const _Impl> _M_impl;
   };
 
+  /// @cond undocumented
+namespace __detail
+{
+  [[noreturn]] inline void
+  __throw_conversion_error()
+  {
+    _GLIBCXX_THROW_OR_ABORT(filesystem_error(
+        "Cannot convert character sequence",
+        std::make_error_code(errc::illegal_byte_sequence)));
+  }
+
+#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+  template<typename _Tp>
+    inline std::wstring
+    __wstr_from_utf8(const _Tp& __str)
+    {
+      static_assert(std::is_same_v<typename _Tp::value_type, char>);
+      std::wstring __wstr;
+      // XXX This assumes native wide encoding is UTF-16.
+      std::codecvt_utf8_utf16<wchar_t> __wcvt;
+      const auto __p = __str.data();
+      if (!__str_codecvt_in_all(__p, __p + __str.size(), __wstr, __wcvt))
+       __detail::__throw_conversion_error();
+      return __wstr;
+    }
+#endif
+
+} // namespace __detail
+  /// @endcond
+
+
   /** Create a path from a UTF-8-encoded sequence of char
    *
    * @relates std::filesystem::path
@@ -846,9 +859,7 @@ namespace __detail
          if (__str_codecvt_out_all(__f, __l, __str, __cvt))
            return __str;
 #endif
-         _GLIBCXX_THROW_OR_ABORT(filesystem_error(
-               "Cannot convert character sequence",
-               std::make_error_code(errc::illegal_byte_sequence)));
+         __detail::__throw_conversion_error();
        }
     }
 
@@ -1058,9 +1069,7 @@ namespace __detail
 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
       } }
 #endif
-      _GLIBCXX_THROW_OR_ABORT(filesystem_error(
-           "Cannot convert character sequence",
-           std::make_error_code(errc::illegal_byte_sequence)));
+      __detail::__throw_conversion_error();
     }
   /// @endcond
 
@@ -1097,9 +1106,7 @@ namespace __detail
     const value_type* __last = __first + _M_pathname.size();
     if (__str_codecvt_out_all(__first, __last, __str, __cvt))
       return __str;
-    _GLIBCXX_THROW_OR_ABORT(filesystem_error(
-         "Cannot convert character sequence",
-         std::make_error_code(errc::illegal_byte_sequence)));
+    __detail::__throw_conversion_error();
 #else
     return _M_pathname;
 #endif