https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102839

            Bug ID: 102839
           Summary: filesystem::path::wstring runs in C locale /
                    practically always throws
           Product: gcc
           Version: 11.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jengelh at inai dot de
  Target Milestone: ---

► cat x.cpp
#include <filesystem>
#include <iostream>
#include <locale>
namespace fs = std::filesystem;
int main()
{
        const char localeName[] = "ja_JP.UTF-8";
        std::setlocale(LC_ALL, localeName);
        std::locale::global(std::locale(localeName));
        fs::path p(u8"壊した");
        std::wcout << p.wstring() << L'\n';
}
 g++ -v x.cpp
Using built-in specs.
Reading specs from /usr/lib64/gcc/x86_64-suse-linux/11/defaults.spec
COLLECT_GCC=/usr/bin/g++
COLLECT_LTO_WRAPPER=/usr/lib64/gcc/x86_64-suse-linux/11/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-suse-linux
Configured with: ../configure --prefix=/usr --infodir=/usr/share/info
--mandir=/usr/share/man --libdir=/usr/lib64 --libexecdir=/usr/lib64
--enable-languages=c,c++,objc,fortran,obj-c++,ada,go,d,jit
--enable-offload-targets=nvptx-none,amdgcn-amdhsa, --without-cuda-driver
--enable-host-shared --enable-checking=release --disable-werror
--with-gxx-include-dir=/usr/include/c++/11 --enable-ssp --disable-libssp
--disable-libvtv --enable-cet=auto --disable-libcc1 --enable-plugin
--with-bugurl=https://bugs.opensuse.org/ --with-pkgversion='SUSE Linux'
--with-slibdir=/lib64 --with-system-zlib --enable-libstdcxx-allocator=new
--disable-libstdcxx-pch --enable-libphobos
--enable-version-specific-runtime-libs --with-gcc-major-version-only
--enable-linker-build-id --enable-linux-futex --enable-gnu-indirect-function
--program-suffix=-11 --without-system-libunwind --enable-multilib
--with-arch-32=x86-64 --with-tune=generic
--with-build-config=bootstrap-lto-lean --enable-link-mutex
--build=x86_64-suse-linux --host=x86_64-suse-linux
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 11.2.1 20210816 [revision 056e324ce46a7924b5cf10f61010cf9dd2ca10e9]
(SUSE Linux) 

► ./a.out 
terminate called after throwing an instance of
'std::filesystem::__cxx11::filesystem_error'
  what():  filesystem error: Cannot convert character sequence: Invalid or
incomplete multibyte or wide character
Aborted (core dumped)

Single-stepping through a -ggdb3 build reveals these code fragments in
libstdc++ which suggest that codecvt<> always operates in C locale:

(x.cpp)
step into
        << p.wstring() <<

leads to

#0  0x00007ffff7e58f09 in std::codecvt<wchar_t, char, __mbstate_t>::codecvt
(this=0x7fffffffdb30, __refs=0) at
../../../../../libstdc++-v3/src/c++98/codecvt.cc:118
116     #ifdef _GLIBCXX_USE_WCHAR_T
117       // codecvt<wchar_t, char, mbstate_t> required specialization
118       codecvt<wchar_t, char, mbstate_t>::
119       codecvt(size_t __refs)
120       : __codecvt_abstract_base<wchar_t, char, mbstate_t>(__refs),
*121       _M_c_locale_codecvt(_S_get_c_locale())
122       { }

std::codecvt<wchar_t, char, __mbstate_t>::do_max_length (this=0x7fffffffdb50)
at codecvt_members.cc:220
217       int
218       codecvt<wchar_t, char, mbstate_t>::
219       do_max_length() const throw()
220       {
221     #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
*222         __c_locale __old = __uselocale(_M_c_locale_codecvt);
223     #endif
224         // XXX Probably wrong for stateful encodings.
225         int __ret = MB_CUR_MAX;
226     #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
227         __uselocale(__old);
228     #endif
229         return __ret;
230       }

Reply via email to