Compare commits

..

1 Commits

Author SHA1 Message Date
c5f5a09be6 - Apply libstdc-Check-conversion-from-filesystem-path-to-wide.patch
- Apply libstdc-Mark-non-exported-function-always_inline.patch
2023-10-20 13:04:34 +03:00
4 changed files with 575 additions and 28 deletions

View File

@ -11384,7 +11384,7 @@
+
--- libstdc++-v3/src/nonshared17/cow-fs_path.cc.libstdc++-compat~ 2021-05-17 12:05:15.746955081 -0400
+++ libstdc++-v3/src/nonshared17/cow-fs_path.cc 2021-05-18 07:06:10.443687154 -0400
@@ -0,0 +1,118 @@
@@ -0,0 +1,130 @@
+// Copyright (C) 2019-2021 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
@ -11408,6 +11408,15 @@
+// <http://www.gnu.org/licenses/>.
+
+#include "../c++17/cow-fs_path.cc"
+asm (".hidden _ZTVSt12codecvt_utf8IwLm1114111ELSt12codecvt_mode0EE");
+asm (".hidden _ZTVNSt10filesystem4path8_CodecvtIwEE");
+asm (".hidden _ZTSSt12codecvt_utf8IwLm1114111ELSt12codecvt_mode0EE");
+asm (".hidden _ZTSNSt10filesystem4path8_CodecvtIwEE");
+asm (".hidden _ZTISt12codecvt_utf8IwLm1114111ELSt12codecvt_mode0EE");
+asm (".hidden _ZTINSt10filesystem4path8_CodecvtIwEE");
+asm (".hidden _ZNSt12codecvt_utf8IwLm1114111ELSt12codecvt_mode0EED0Ev");
+asm (".hidden _ZNSt12codecvt_utf8IwLm1114111ELSt12codecvt_mode0EED1Ev");
+asm (".hidden _ZNSt12codecvt_utf8IwLm1114111ELSt12codecvt_mode0EED2Ev");
+asm (".hidden _ZNKSt12__shared_ptrIKNSt10filesystem16filesystem_error5_ImplELN9__gnu_cxx12_Lock_policyE2EE14_M_get_deleterERKSt9type_info");
+asm (".hidden _ZNKSt12__shared_ptrIKNSt10filesystem16filesystem_error5_ImplELN9__gnu_cxx12_Lock_policyE2EE3getEv");
+asm (".hidden _ZNKSt12__shared_ptrIKNSt10filesystem16filesystem_error5_ImplELN9__gnu_cxx12_Lock_policyE2EE6uniqueEv");
@ -11422,6 +11431,9 @@
+asm (".hidden _ZNSt10filesystem4path5_ListaSERKS1_");
+asm (".hidden _ZNSt10filesystem4path5_ListC2ERKS1_");
+asm (".hidden _ZNSt10filesystem4path5_ListC2Ev");
+asm (".hidden _ZNSt10filesystem4path8_CodecvtIwED0Ev");
+asm (".hidden _ZNSt10filesystem4path8_CodecvtIwED1Ev");
+asm (".hidden _ZNSt10filesystem4path8_CodecvtIwED2Ev");
+asm (".hidden _ZNSt12__shared_ptrIKNSt10filesystem16filesystem_error5_ImplELN9__gnu_cxx12_Lock_policyE2EE4swapERS6_");
+asm (".hidden _ZNSt12__shared_ptrIKNSt10filesystem16filesystem_error5_ImplELN9__gnu_cxx12_Lock_policyE2EE5resetEv");
+asm (".hidden _ZNSt12__shared_ptrIKNSt10filesystem16filesystem_error5_ImplELN9__gnu_cxx12_Lock_policyE2EEaSEOS6_");
@ -11467,17 +11479,17 @@
+asm (".hidden _ZNKSt10filesystem4path5_List5_Impl4copyEv");
+asm (".hidden _ZNSt10filesystem4path10_S_convertIwEEDaPKT_S4_");
+asm (".hidden _ZNSt10filesystem8__detail24__throw_conversion_errorEv");
+asm (".hidden _ZTIZNSt10filesystem4path10_S_convertIwEEDaPKT_S4_E5_UCvt");
+asm (".hidden _ZTSZNSt10filesystem4path10_S_convertIwEEDaPKT_S4_E5_UCvt");
+asm (".hidden _ZTVZNSt10filesystem4path10_S_convertIwEEDaPKT_S4_E5_UCvt");
+asm (".hidden _ZZNSt10filesystem4path10_S_convertIwEEDaPKT_S4_EN5_UCvtD0Ev");
+asm (".hidden _ZZNSt10filesystem4path10_S_convertIwEEDaPKT_S4_EN5_UCvtD1Ev");
+asm (".hidden _ZZNSt10filesystem4path10_S_convertIwEEDaPKT_S4_EN5_UCvtD2Ev");
+asm (".hidden _ZNSt10filesystem4path5_List5beginEv");
+asm (".hidden _ZNSt10filesystem4path7_Parser4nextEv");
+asm (".hidden _ZNSt10filesystem4pathD1Ev");
+asm (".hidden _ZNSt10filesystem4pathD2Ev");
+#ifndef __i386__
+//asm (".hidden _ZTVZNSt10filesystem4path10_S_convertIwEEDaPKT_S4_E5_UCvt");
+//asm (".hidden _ZZNSt10filesystem4path10_S_convertIwEEDaPKT_S4_EN5_UCvtD1Ev");
+//asm (".hidden _ZZNSt10filesystem4path10_S_convertIwEEDaPKT_S4_EN5_UCvtD0Ev");
+//asm (".hidden _ZTIZNSt10filesystem4path10_S_convertIwEEDaPKT_S4_E5_UCvt");
+//asm (".hidden _ZTSZNSt10filesystem4path10_S_convertIwEEDaPKT_S4_E5_UCvt");
+//asm (".hidden _ZZNSt10filesystem4path10_S_convertIwEEDaPKT_S4_EN5_UCvtD2Ev");
+asm (".hidden _ZNSbIwSt11char_traitsIwESaIwEE6resizeEmw");
+asm (".hidden _ZNSbIwSt11char_traitsIwESaIwEE7reserveEm");
+asm (".hidden _ZNSbIwSt11char_traitsIwESaIwEE9_M_mutateEmmm");
@ -11610,7 +11622,7 @@
+asm (".hidden _ZNSt10filesystem7__cxx114_Dir7advanceEbRSt10error_code");
+asm (".hidden _ZNSt10filesystem7__cxx114_DirD1Ev");
+asm (".hidden _ZNSt10filesystem7__cxx114_DirD2Ev");
+#ifdef __x86_64__
+#if defined(__x86_64__) || defined(__i386__)
+asm (".hidden _ZNSt10filesystem9_Dir_base7advanceEbRSt10error_code");
+//asm (".hidden _ZNSt10filesystem9_Dir_baseC1EPKcbRSt10error_code");
+//asm (".hidden _ZNSt10filesystem9_Dir_baseC2EPKcbRSt10error_code");
@ -11671,7 +11683,7 @@
+#endif
--- libstdc++-v3/src/nonshared17/fs_path80.cc.libstdc++-compat~ 2021-05-17 12:05:15.766954365 -0400
+++ libstdc++-v3/src/nonshared17/fs_path80.cc 2021-05-18 07:26:42.069574900 -0400
@@ -0,0 +1,51 @@
@@ -0,0 +1,61 @@
+// Copyright (C) 2019-2021 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
@ -11696,17 +11708,21 @@
+
+#define _GLIBCXX_NONSHARED_CXX17_80
+#include "fs_path.cc"
+#if !defined(__powerpc64__) && !defined(__s390x__) && !defined(__i386__)
+asm (".hidden _ZTVSt12codecvt_utf8IwLm1114111ELSt12codecvt_mode0EE");
+asm (".hidden _ZTVNSt10filesystem7__cxx114path8_CodecvtIwEE");
+asm (".hidden _ZTSSt12codecvt_utf8IwLm1114111ELSt12codecvt_mode0EE");
+asm (".hidden _ZTSNSt10filesystem7__cxx114path8_CodecvtIwEE");
+asm (".hidden _ZTISt12codecvt_utf8IwLm1114111ELSt12codecvt_mode0EE");
+asm (".hidden _ZTINSt10filesystem7__cxx114path8_CodecvtIwEE");
+asm (".hidden _ZNSt10filesystem7__cxx114path10_S_convertIwEEDaPKT_S5_");
+#endif
+asm (".hidden _ZNSt10filesystem7__cxx118__detail24__throw_conversion_errorEv");
+asm (".hidden _ZTIZNSt10filesystem7__cxx114path10_S_convertIwEEDaPKT_S5_E5_UCvt");
+asm (".hidden _ZTSZNSt10filesystem7__cxx114path10_S_convertIwEEDaPKT_S5_E5_UCvt");
+asm (".hidden _ZTVZNSt10filesystem7__cxx114path10_S_convertIwEEDaPKT_S5_E5_UCvt");
+asm (".hidden _ZZNSt10filesystem7__cxx114path10_S_convertIwEEDaPKT_S5_EN5_UCvtD0Ev");
+asm (".hidden _ZZNSt10filesystem7__cxx114path10_S_convertIwEEDaPKT_S5_EN5_UCvtD1Ev");
+asm (".hidden _ZZNSt10filesystem7__cxx114path10_S_convertIwEEDaPKT_S5_EN5_UCvtD2Ev");
+asm (".hidden _ZNKSt10filesystem7__cxx114path5_List5_Impl4copyEv");
+asm (".hidden _ZNSt10filesystem7__cxx114path8_CodecvtIwED0Ev");
+asm (".hidden _ZNSt10filesystem7__cxx114path8_CodecvtIwED1Ev");
+asm (".hidden _ZNSt10filesystem7__cxx114path8_CodecvtIwED2Ev");
+asm (".hidden _ZNSt12codecvt_utf8IwLm1114111ELSt12codecvt_mode0EED0Ev");
+asm (".hidden _ZNSt12codecvt_utf8IwLm1114111ELSt12codecvt_mode0EED1Ev");
+asm (".hidden _ZNSt12codecvt_utf8IwLm1114111ELSt12codecvt_mode0EED2Ev");
+#ifdef __i386__
+asm (".hidden _ZNSt12system_errorC1ESt10error_codeRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE");
+asm (".hidden _ZNSt12system_errorC2ESt10error_codeRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE");
@ -11717,6 +11733,12 @@
+asm (".hidden _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6resizeEjc");
+#endif
+#ifndef __i386__
+//asm (".hidden _ZZNSt10filesystem7__cxx114path10_S_convertIwEEDaPKT_S5_EN5_UCvtD2Ev");
+//asm (".hidden _ZZNSt10filesystem7__cxx114path10_S_convertIwEEDaPKT_S5_EN5_UCvtD0Ev");
+//asm (".hidden _ZTIZNSt10filesystem7__cxx114path10_S_convertIwEEDaPKT_S5_E5_UCvt");
+//asm (".hidden _ZTVZNSt10filesystem7__cxx114path10_S_convertIwEEDaPKT_S5_E5_UCvt");
+//asm (".hidden _ZZNSt10filesystem7__cxx114path10_S_convertIwEEDaPKT_S5_EN5_UCvtD1Ev");
+//asm (".hidden _ZTSZNSt10filesystem7__cxx114path10_S_convertIwEEDaPKT_S5_E5_UCvt");
+asm (".hidden _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE10_M_replaceEmmPKcm");
+asm (".hidden _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6resizeEmc");
+asm (".hidden _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7reserveEm");
@ -11762,7 +11784,7 @@
+asm (".hidden _ZNSt10filesystem4_Dir7advanceEbRSt10error_code");
+asm (".hidden _ZNSt10filesystem4_DirD1Ev");
+asm (".hidden _ZNSt10filesystem4_DirD2Ev");
+#ifdef __x86_64__
+#if defined(__x86_64__) || defined(__i386__)
+asm (".hidden _ZNSt10filesystem9_Dir_base7advanceEbRSt10error_code");
+//asm (".hidden _ZNSt10filesystem9_Dir_baseC1EPKcbRSt10error_code");
+//asm (".hidden _ZNSt10filesystem9_Dir_baseC2EPKcbRSt10error_code");
@ -11968,7 +11990,7 @@
+ $(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
--- libstdc++-v3/src/nonshared17/fs_path.cc.libstdc++-compat~ 2021-05-17 12:05:15.766954365 -0400
+++ libstdc++-v3/src/nonshared17/fs_path.cc 2021-05-18 07:27:17.368310028 -0400
@@ -0,0 +1,95 @@
@@ -0,0 +1,93 @@
+// Copyright (C) 2019-2021 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
@ -12042,18 +12064,16 @@
+asm (".hidden _ZNSt12system_errorC2ESt10error_codeRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE");
+asm (".hidden _ZNSt15__allocated_ptrISaISt23_Sp_counted_ptr_inplaceINSt10filesystem7__cxx1116filesystem_error5_ImplESaIS4_ELN9__gnu_cxx12_Lock_policyE2EEEED1Ev");
+asm (".hidden _ZNSt15__allocated_ptrISaISt23_Sp_counted_ptr_inplaceINSt10filesystem7__cxx1116filesystem_error5_ImplESaIS4_ELN9__gnu_cxx12_Lock_policyE2EEEED2Ev");
+#if !defined (__aarch64__) && !defined (__x86_64__)
+#ifndef __i386__
+//asm (".hidden _ZZNSt10filesystem7__cxx114path10_S_convertIwEEDaPKT_S5_EN5_UCvtD0Ev");
+//asm (".hidden _ZTIZNSt10filesystem7__cxx114path10_S_convertIwEEDaPKT_S5_E5_UCvt");
+//asm (".hidden _ZTVZNSt10filesystem7__cxx114path10_S_convertIwEEDaPKT_S5_E5_UCvt");
+//asm (".hidden _ZTSZNSt10filesystem7__cxx114path10_S_convertIwEEDaPKT_S5_E5_UCvt");
+//asm (".hidden _ZNSt10filesystem7__cxx114pathaSISt17basic_string_viewIcSt11char_traitsIcEEEERNSt9enable_ifIXsrSt6__and_IISt6__not_ISt7is_sameINSt9remove_cvIT_E4typeES1_EES9_ISt7is_voidINSt14remove_pointerISC_E4typeEEENS0_8__detail20__constructible_fromISC_vEEEE5valueES1_E4typeERKSC_");
+//asm (".hidden _ZNSt10filesystem7__cxx114pathaSISt17basic_string_viewIcSt11char_traitsIcEEEERNSt9enable_ifIXsrSt6__and_IJSt6__not_ISt7is_sameINSt9remove_cvIT_E4typeES1_EES9_ISt7is_voidINSt14remove_pointerISC_E4typeEEENS0_8__detail20__constructible_fromISC_vEEEE5valueES1_E4typeERKSC_");
+//asm (".hidden _ZZNSt10filesystem7__cxx114path10_S_convertIwEEDaPKT_S5_EN5_UCvtD1Ev");
+//asm (".hidden _ZZNSt10filesystem7__cxx114path10_S_convertIwEEDaPKT_S5_EN5_UCvtD2Ev");
+#endif
+#endif
+asm (".hidden _ZTIZNSt10filesystem7__cxx114path10_S_convertIwEEDaPKT_S5_E5_UCvt");
+asm (".hidden _ZTSZNSt10filesystem7__cxx114path10_S_convertIwEEDaPKT_S5_E5_UCvt");
+asm (".hidden _ZTVZNSt10filesystem7__cxx114path10_S_convertIwEEDaPKT_S5_E5_UCvt");
+asm (".hidden _ZZNSt10filesystem7__cxx114path10_S_convertIwEEDaPKT_S5_EN5_UCvtD0Ev");
+asm (".hidden _ZZNSt10filesystem7__cxx114path10_S_convertIwEEDaPKT_S5_EN5_UCvtD1Ev");
+asm (".hidden _ZZNSt10filesystem7__cxx114path10_S_convertIwEEDaPKT_S5_EN5_UCvtD2Ev");
+asm (".hidden _ZNSt10filesystem7__cxx114path5_List5beginEv");
+asm (".hidden _ZNSt10filesystem7__cxx114path7_Parser4nextEv");
+#if !defined(__powerpc64__) && !defined(__s390x__) && !defined(__i386__)

View File

@ -0,0 +1,470 @@
From d308b11fa94728507984b4ccc949219511273ab6 Mon Sep 17 00:00:00 2001
From: Jonathan Wakely <jwakely@redhat.com>
Date: Fri, 11 Nov 2022 15:22:02 +0000
Subject: [PATCH] libstdc++: Fix wstring conversions in filesystem::path
[PR95048]
In commit r9-7381-g91756c4abc1757 I changed filesystem::path to use
std::codecvt<CharT, char, mbstate_t> for conversions from all wide
strings to UTF-8, instead of using std::codecvt_utf8<CharT>. This was
done because for 16-bit wchar_t, std::codecvt_utf8<wchar_t> only
supports UCS-2 and not UTF-16. The rationale for the change was sound,
but the actual fix was not. It's OK to use std::codecvt for char16_t or
char32_t, because the specializations for those types always use UTF-8 ,
but std::codecvt<wchar_t, char, mbstate_t> uses the current locale's
encodings, and the narrow encoding is probably ASCII and can't support
non-ASCII characters.
The correct fix is to use std::codecvt only for char16_t and char32_t.
For 32-bit wchar_t we could have continued using std::codecvt_utf8
because that uses UTF-32 which is fine, switching to std::codecvt broke
non-Windows targets with 32-bit wchar_t. For 16-bit wchar_t we did need
to change, but should have changed to std::codecvt_utf8_utf16<wchar_t>
instead, as that always uses UTF-16 not UCS-2. I actually noted that in
the commit message for r9-7381-g91756c4abc1757 but didn't use that
option. Oops.
This replaces the unconditional std::codecvt<CharT, char, mbstate_t>
with a type defined via template specialization, so it can vary
depending on the wide character type. The code is also simplified to
remove some of the mess of #ifdef and if-constexpr conditions.
libstdc++-v3/ChangeLog:
PR libstdc++/95048
* include/bits/fs_path.h (path::_Codecvt): New class template
that selects the kind of code conversion done.
(path::_Codecvt<wchar_t>): Select based on sizeof(wchar_t).
(_GLIBCXX_CONV_FROM_UTF8): New macro to allow the same code to
be used for Windows and POSIX.
(path::_S_convert(const EcharT*, const EcharT*)): Simplify by
using _Codecvt and _GLIBCXX_CONV_FROM_UTF8 abstractions.
(path::_S_str_convert(basic_string_view<value_type>, const A&)):
Simplify nested conditions.
* include/experimental/bits/fs_path.h (path::_Cvt): Define
nested typedef controlling type of code conversion done.
(path::_Cvt::_S_wconvert): Use new typedef.
(path::string(const A&)): Likewise.
* testsuite/27_io/filesystem/path/construct/95048.cc: New test.
* testsuite/experimental/filesystem/path/construct/95048.cc: New
test.
(cherry picked from commit b331bf303bdc1edead41e2b3d11d1a7804b433cf)
---
libstdc++-v3/include/bits/fs_path.h | 126 ++++++++++--------
.../include/experimental/bits/fs_path.h | 53 ++++++--
.../27_io/filesystem/path/construct/95048.cc | 45 +++++++
.../filesystem/path/construct/95048.cc | 47 +++++++
4 files changed, 204 insertions(+), 67 deletions(-)
create mode 100644 libstdc++-v3/testsuite/27_io/filesystem/path/construct/95048.cc
create mode 100644 libstdc++-v3/testsuite/experimental/filesystem/path/construct/95048.cc
diff --git a/libstdc++-v3/include/bits/fs_path.h b/libstdc++-v3/include/bits/fs_path.h
index 1188e585b14c..029a6f365b3a 100644
--- a/libstdc++-v3/include/bits/fs_path.h
+++ b/libstdc++-v3/include/bits/fs_path.h
@@ -684,6 +684,8 @@ namespace __detail
_List _M_cmpts;
struct _Parser;
+
+ template<typename _EcharT> struct _Codecvt;
};
/// @{
@@ -811,55 +813,72 @@ namespace __detail
size_t _M_pos;
};
+ // path::_Codecvt<C> Performs conversions between C and path::string_type.
+ // The native encoding of char strings is the OS-dependent current
+ // encoding for pathnames. FIXME: We assume this is UTF-8 everywhere,
+ // but should use a Windows API to query it.
+
+ // Converts between native pathname encoding and char16_t or char32_t.
+ template<typename _EcharT>
+ struct path::_Codecvt
+ // Need derived class here because std::codecvt has protected destructor.
+ : std::codecvt<_EcharT, char, mbstate_t>
+ { };
+
+ // Converts between native pathname encoding and native wide encoding.
+ // The native encoding for wide strings is the execution wide-character
+ // set encoding. FIXME: We assume that this is either UTF-32 or UTF-16
+ // (depending on the width of wchar_t). That matches GCC's default,
+ // but can be changed with -fwide-exec-charset.
+ // We need a custom codecvt converting the native pathname encoding
+ // to/from the native wide encoding.
+ template<>
+ struct path::_Codecvt<wchar_t>
+ : conditional_t<sizeof(wchar_t) == sizeof(char32_t),
+ std::codecvt_utf8<wchar_t>, // UTF-8 <-> UTF-32
+ std::codecvt_utf8_utf16<wchar_t>> // UTF-8 <-> UTF-16
+ { };
+
template<typename _EcharT>
auto
path::_S_convert(const _EcharT* __f, const _EcharT* __l)
{
static_assert(__detail::__is_encoded_char<_EcharT>);
+#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+# define _GLIBCXX_CONV_FROM_UTF8(S) __detail::__wstr_from_utf8(S)
+#else
+# define _GLIBCXX_CONV_FROM_UTF8(S) S
+#endif
+
if constexpr (is_same_v<_EcharT, value_type>)
return basic_string_view<value_type>(__f, __l - __f);
-#if !defined _GLIBCXX_FILESYSTEM_IS_WINDOWS && defined _GLIBCXX_USE_CHAR8_T
+#ifdef _GLIBCXX_USE_CHAR8_T
else if constexpr (is_same_v<_EcharT, char8_t>)
- // For POSIX converting from char8_t to char is also 'noconv'
- return string_view(reinterpret_cast<const char*>(__f), __l - __f);
-#endif
- else
{
+ string_view __str(reinterpret_cast<const char*>(__f), __l - __f);
+ return _GLIBCXX_CONV_FROM_UTF8(__str);
+ }
+#endif
#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+ else if constexpr (is_same_v<_EcharT, char>)
+ {
std::wstring __wstr;
- if constexpr (is_same_v<_EcharT, char>)
- {
- struct _UCvt : std::codecvt<wchar_t, char, std::mbstate_t>
- { } __cvt;
- if (__str_codecvt_in_all(__f, __l, __wstr, __cvt))
- return __wstr;
- }
-#ifdef _GLIBCXX_USE_CHAR8_T
- else if constexpr (is_same_v<_EcharT, char8_t>)
- {
- const auto __f2 = reinterpret_cast<const char*>(__f);
- return __detail::__wstr_from_utf8(string_view(__f2, __l - __f));
- }
+ path::_Codecvt<wchar_t> __cvt;
+ if (__str_codecvt_in_all(__f, __l, __wstr, __cvt))
+ return __wstr;
+ }
#endif
- else // char16_t or char32_t
- {
- struct _UCvt : std::codecvt<_EcharT, char, std::mbstate_t>
- { } __cvt;
- std::string __str;
- if (__str_codecvt_out_all(__f, __l, __str, __cvt))
- return __detail::__wstr_from_utf8(__str);
- }
-#else // ! windows
- struct _UCvt : std::codecvt<_EcharT, char, std::mbstate_t>
- { } __cvt;
+ else
+ {
+ path::_Codecvt<_EcharT> __cvt;
std::string __str;
if (__str_codecvt_out_all(__f, __l, __str, __cvt))
- return __str;
-#endif
- __detail::__throw_conversion_error();
+ return _GLIBCXX_CONV_FROM_UTF8(__str);
}
+ __detail::__throw_conversion_error();
}
+#undef _GLIBCXX_CONV_FROM_UTF8
/// @endcond
@@ -1028,7 +1047,9 @@ namespace __detail
if (__str.size() == 0)
return _WString(__a);
-#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+#ifndef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+ string_view __u8str = __str;
+#else
// First convert native string from UTF-16 to to UTF-8.
// XXX This assumes that the execution wide-character set is UTF-16.
std::codecvt_utf8_utf16<value_type> __cvt;
@@ -1038,35 +1059,30 @@ namespace __detail
_String __u8str{_CharAlloc{__a}};
const value_type* __wfirst = __str.data();
const value_type* __wlast = __wfirst + __str.size();
- if (__str_codecvt_out_all(__wfirst, __wlast, __u8str, __cvt)) {
+ if (!__str_codecvt_out_all(__wfirst, __wlast, __u8str, __cvt))
+ __detail::__throw_conversion_error();
if constexpr (is_same_v<_CharT, char>)
return __u8str; // XXX assumes native ordinary encoding is UTF-8.
- else {
-
- const char* __first = __u8str.data();
- const char* __last = __first + __u8str.size();
-#else
- const value_type* __first = __str.data();
- const value_type* __last = __first + __str.size();
-#endif
-
- // Convert UTF-8 string to requested format.
-#ifdef _GLIBCXX_USE_CHAR8_T
- if constexpr (is_same_v<_CharT, char8_t>)
- return _WString(__first, __last, __a);
else
#endif
{
- // Convert UTF-8 to wide string.
- _WString __wstr(__a);
- struct _UCvt : std::codecvt<_CharT, char, std::mbstate_t> { } __cvt;
- if (__str_codecvt_in_all(__first, __last, __wstr, __cvt))
- return __wstr;
- }
+ const char* __first = __u8str.data();
+ const char* __last = __first + __u8str.size();
-#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
- } }
+ // Convert UTF-8 string to requested format.
+#ifdef _GLIBCXX_USE_CHAR8_T
+ if constexpr (is_same_v<_CharT, char8_t>)
+ return _WString(__first, __last, __a);
+ else
#endif
+ {
+ // Convert UTF-8 to wide string.
+ _WString __wstr(__a);
+ path::_Codecvt<_CharT> __cvt;
+ if (__str_codecvt_in_all(__first, __last, __wstr, __cvt))
+ return __wstr;
+ }
+ }
__detail::__throw_conversion_error();
}
/// @endcond
diff --git a/libstdc++-v3/include/experimental/bits/fs_path.h b/libstdc++-v3/include/experimental/bits/fs_path.h
index 830b51e45a0f..65d63e433e08 100644
--- a/libstdc++-v3/include/experimental/bits/fs_path.h
+++ b/libstdc++-v3/include/experimental/bits/fs_path.h
@@ -748,15 +748,48 @@ namespace __detail
template<>
struct path::_Cvt<path::value_type>
{
+ // We need this type to be defined because we don't have `if constexpr`
+ // in C++11 and so path::string<C,T,A>(const A&) needs to be able to
+ // declare a variable of this type and pass it to __str_codecvt_in_all.
+ using __codecvt_utf8_to_wide = _Cvt;
+ // Dummy overload used for unreachable calls in path::string<C,T,A>.
+ template<typename _WStr>
+ friend bool
+ __str_codecvt_in_all(const char*, const char*,
+ _WStr&, __codecvt_utf8_to_wide&) noexcept
+ { return true; }
+
template<typename _Iter>
static string_type
_S_convert(_Iter __first, _Iter __last)
{ return string_type{__first, __last}; }
};
+ // Performs conversions from _CharT to path::string_type.
template<typename _CharT>
struct path::_Cvt
{
+ // FIXME: We currently assume that the native wide encoding for wchar_t
+ // is either UTF-32 or UTF-16 (depending on the width of wchar_t).
+ // See comments in <bits/fs_path.h> for further details.
+ using __codecvt_utf8_to_wchar
+ = typename conditional<sizeof(wchar_t) == sizeof(char32_t),
+ std::codecvt_utf8<wchar_t>, // from UTF-32
+ std::codecvt_utf8_utf16<wchar_t> // from UTF-16
+ >::type;
+
+ // Converts from char16_t or char32_t using std::codecvt<charNN_t, char>.
+ // Need derived class here because std::codecvt has protected destructor.
+ struct __codecvt_utf8_to_utfNN : std::codecvt<_CharT, char, mbstate_t>
+ { };
+
+ // Convert from native pathname format (assumed to be UTF-8 everywhere)
+ // to the encoding implied by the wide character type _CharT.
+ using __codecvt_utf8_to_wide
+ = typename conditional<is_same<_CharT, wchar_t>::value,
+ __codecvt_utf8_to_wchar,
+ __codecvt_utf8_to_utfNN>::type;
+
#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
#ifdef _GLIBCXX_USE_CHAR8_T
static string_type
@@ -774,8 +807,7 @@ namespace __detail
static string_type
_S_wconvert(const char* __f, const char* __l, const char*)
{
- using _Cvt = std::codecvt<wchar_t, char, mbstate_t>;
- const auto& __cvt = std::use_facet<_Cvt>(std::locale{});
+ std::codecvt_utf8_utf16<wchar_t> __cvt;
std::wstring __wstr;
if (__str_codecvt_in_all(__f, __l, __wstr, __cvt))
return __wstr;
@@ -787,8 +819,7 @@ namespace __detail
static string_type
_S_wconvert(const _CharT* __f, const _CharT* __l, const void*)
{
- struct _UCvt : std::codecvt<_CharT, char, std::mbstate_t>
- { } __cvt;
+ __codecvt_utf8_to_wide __cvt;
std::string __str;
if (__str_codecvt_out_all(__f, __l, __str, __cvt))
{
@@ -819,8 +850,7 @@ namespace __detail
else
#endif
{
- struct _UCvt : std::codecvt<_CharT, char, std::mbstate_t>
- { } __cvt;
+ __codecvt_utf8_to_wide __cvt;
std::string __str;
if (__str_codecvt_out_all(__f, __l, __str, __cvt))
return __str;
@@ -990,7 +1020,7 @@ namespace __detail
inline std::basic_string<_CharT, _Traits, _Allocator>
path::string(const _Allocator& __a) const
{
- if (is_same<_CharT, value_type>::value)
+ if _GLIBCXX_CONSTEXPR (is_same<_CharT, value_type>::value)
return { _M_pathname.begin(), _M_pathname.end(), __a };
using _WString = basic_string<_CharT, _Traits, _Allocator>;
@@ -1026,9 +1056,8 @@ namespace __detail
else
#endif
{
- // Convert UTF-8 to wide string.
- struct _UCvt : std::codecvt<_CharT, char, std::mbstate_t>
- { } __cvt;
+ // Convert UTF-8 to char16_t or char32_t string.
+ typename path::_Cvt<_CharT>::__codecvt_utf8_to_wide __cvt;
const char* __f = __from.data();
const char* __l = __f + __from.size();
if (__str_codecvt_in_all(__f, __l, __to, __cvt))
@@ -1041,14 +1070,14 @@ namespace __detail
if (auto* __p = __dispatch(__u8str, __wstr, is_same<_CharT, char>{}))
return *__p;
}
-#else
+#else // ! Windows
#ifdef _GLIBCXX_USE_CHAR8_T
if constexpr (is_same<_CharT, char8_t>::value)
return _WString(__first, __last, __a);
else
#endif
{
- struct _UCvt : std::codecvt<_CharT, char, std::mbstate_t> { } __cvt;
+ typename path::_Cvt<_CharT>::__codecvt_utf8_to_wide __cvt;
_WString __wstr(__a);
if (__str_codecvt_in_all(__first, __last, __wstr, __cvt))
return __wstr;
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/construct/95048.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/construct/95048.cc
new file mode 100644
index 000000000000..c1a382d14204
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/filesystem/path/construct/95048.cc
@@ -0,0 +1,45 @@
+// { dg-do run { target c++17 } }
+
+// C++17 30.10.8.4.1 path constructors [fs.path.construct]
+
+#include <filesystem>
+#include <testsuite_hooks.h>
+
+using std::filesystem::path;
+
+#define CHECK(E, S) (path(E##S) == path(u8##S))
+
+void
+test_wide()
+{
+ VERIFY( CHECK(L, "\u00E4") ); // PR libstdc++/95048
+ VERIFY( CHECK(L, "\U0001F4C1") ); // folder
+ VERIFY( CHECK(L, "\U0001F4C2") ); // open folder
+ VERIFY( CHECK(L, "\U0001F4C4") ); // filing cabient
+}
+
+void
+test_u16()
+{
+ VERIFY( CHECK(u, "\u00E4") ); // PR libstdc++/95048
+ VERIFY( CHECK(u, "\U0001F4C1") ); // folder
+ VERIFY( CHECK(u, "\U0001F4C2") ); // open folder
+ VERIFY( CHECK(u, "\U0001F4C4") ); // filing cabient
+}
+
+void
+test_u32()
+{
+ VERIFY( CHECK(U, "\u00E4") ); // PR libstdc++/95048
+ VERIFY( CHECK(U, "\U0001F4C1") ); // folder
+ VERIFY( CHECK(U, "\U0001F4C2") ); // open folder
+ VERIFY( CHECK(U, "\U0001F4C4") ); // filing cabient
+}
+
+int
+main()
+{
+ test_wide();
+ test_u16();
+ test_u32();
+}
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/construct/95048.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/construct/95048.cc
new file mode 100644
index 000000000000..b7a93f3c9856
--- /dev/null
+++ b/libstdc++-v3/testsuite/experimental/filesystem/path/construct/95048.cc
@@ -0,0 +1,47 @@
+// { dg-options "-lstdc++fs" }
+// { dg-do run { target c++11 } }
+// { dg-require-filesystem-ts "" }
+
+// 8.4.1 path constructors [path.construct]
+
+#include <experimental/filesystem>
+#include <testsuite_hooks.h>
+
+using std::experimental::filesystem::path;
+
+#define CHECK(E, S) (path(E##S) == path(u8##S))
+
+void
+test_wide()
+{
+ VERIFY( CHECK(L, "\u00E4") ); // PR libstdc++/95048
+ VERIFY( CHECK(L, "\U0001F4C1") ); // folder
+ VERIFY( CHECK(L, "\U0001F4C2") ); // open folder
+ VERIFY( CHECK(L, "\U0001F4C4") ); // filing cabient
+}
+
+void
+test_u16()
+{
+ VERIFY( CHECK(u, "\u00E4") ); // PR libstdc++/95048
+ VERIFY( CHECK(u, "\U0001F4C1") ); // folder
+ VERIFY( CHECK(u, "\U0001F4C2") ); // open folder
+ VERIFY( CHECK(u, "\U0001F4C4") ); // filing cabient
+}
+
+void
+test_u32()
+{
+ VERIFY( CHECK(U, "\u00E4") ); // PR libstdc++/95048
+ VERIFY( CHECK(U, "\U0001F4C1") ); // folder
+ VERIFY( CHECK(U, "\U0001F4C2") ); // open folder
+ VERIFY( CHECK(U, "\U0001F4C4") ); // filing cabient
+}
+
+int
+main()
+{
+ test_wide();
+ test_u16();
+ test_u32();
+}
--
2.39.3

View File

@ -0,0 +1,43 @@
From 03af8492bee6243a9d10e78fea1a3e423bd5f9cd Mon Sep 17 00:00:00 2001
From: Jonathan Wakely <jwakely@redhat.com>
Date: Fri, 27 May 2022 12:43:18 +0100
Subject: [PATCH] libstdc++: Mark non-exported function always_inline
[PR105671]
This new function was added for gcc 11.1 but is not exported from the
shared library. Depending on inlining decisions, its callers might get
inlined but an external definition be needed for this function. That
then fails to link.
Since we can't add the export to the gcc-11 release branch now, mark it
always_inline. We can consider exporting it for gcc-13 if/when we bump
the shared library version (and maybe also for gcc-12 which is currently
at the same version as trunk). For now, the attribute will solve the
problem on all affected branches. The function is small enough that
force-inlining it shouldn't cause problems.
libstdc++-v3/ChangeLog:
PR libstdc++/105671
* include/std/sstream (basic_stringbuf::_M_high_mark): Add
always_inline attribute.
(cherry picked from commit de57440858591a88e8fd7ba2505ca54546c86021)
---
libstdc++-v3/include/std/sstream | 1 +
1 file changed, 1 insertion(+)
diff --git a/libstdc++-v3/include/std/sstream b/libstdc++-v3/include/std/sstream
index f21664100ab8..56555ecd98a1 100644
--- a/libstdc++-v3/include/std/sstream
+++ b/libstdc++-v3/include/std/sstream
@@ -425,6 +425,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
// This might not be the same character as _M_string.end() because
// basic_stringbuf::overflow might have written to unused capacity
// in _M_string without updating its length.
+ __attribute__((__always_inline__))
char_type*
_M_high_mark() const _GLIBCXX_NOEXCEPT
{
--
2.39.3

View File

@ -138,7 +138,7 @@
Summary: GCC version 11
Name: %{?scl_prefix}gcc
Version: %{gcc_version}
Release: %{gcc_release}.1%{?dist}
Release: %{gcc_release}.2%{?dist}.alma.1
# libgcc, libgfortran, libgomp, libstdc++ and crtstuff have
# GCC Runtime Exception.
License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ with exceptions and LGPLv2+ and BSD
@ -344,6 +344,11 @@ Patch16: gcc11-stringify-__VA_OPT__.patch
Patch17: gcc11-stringify-__VA_OPT__-2.patch
Patch18: gcc11-Wbidi-chars.patch
Patch19: gcc11-dejagnu-multiline.patch
# Patches were taken from upstream:
# https://gcc.gnu.org/git/?p=gcc.git;a=patch;h=03af8492bee6243a9d10e78fea1a3e423bd5f9cd
Patch20: libstdc-Mark-non-exported-function-always_inline.patch
# https://gcc.gnu.org/git/?p=gcc.git;a=patch;h=d308b11fa94728507984b4ccc949219511273ab6
Patch21: libstdc-Check-conversion-from-filesystem-path-to-wide.patch
Patch100: gcc11-fortran-fdec-duplicates.patch
Patch101: gcc11-fortran-flogical-as-integer.patch
@ -385,6 +390,9 @@ Patch3012: 0016-Conditionalize-test-for-hashtable-bucket-sizes-on-__.patch
Patch3013: 0017-Conditionalize-test-for-PR-libstdc-71181-on-__LIBSTD.patch
Patch3014: gcc11-dg-ice-fixes.patch
%if 0%{?rhel} > 7
%global nonsharedver 80
%else
@ -719,6 +727,8 @@ to NVidia PTX capable devices if available.
%patch17 -p0 -b .stringify-__VA_OPT__-2~
%patch18 -p1 -b .bidi~
%patch19 -p1 -b .dejagnu-multiline~
%patch20 -p1 -b .libstdc++-mark~
%patch21 -p1 -b .libstdc++-check~
%patch100 -p1 -b .fortran-fdec-duplicates~
%patch101 -p1 -b .fortran-flogical-as-integer~
@ -2892,6 +2902,10 @@ fi
%endif
%changelog
* Fri Oct 20 2023 Eduard Abdullin <eabdullin@almalinux.org> 11.2.1-9.2.alma.1
- Apply libstdc-Check-conversion-from-filesystem-path-to-wide.patch
- Apply libstdc-Mark-non-exported-function-always_inline.patch
* Wed Feb 2 2022 Marek Polacek <polacek@redhat.com> 11.2.1-9.1
- avoid overly-greedy match in dejagnu regexp (#2049712)