When I refactored the filesystem_error code I changed it to only use the
constructor parameter in the what() string, instead of the string
returned by system_error::what(). That meant it no longer included the
description of the error_code that system_error adds. This restores the
previous behaivour, as encouraged by the standard ("Implementations
should include the system_error::what() string and the pathnames of
path1 and path2 in the native format in the returned string").

        PR libstdc++/91012
        * src/c++17/fs_path.cc (filesystem_error::_Impl): Use a string_view
        for the what_arg parameters.
        (filesystem_error::filesystem_error): Pass system_error::what() to
        the _Impl constructor.
        * testsuite/27_io/filesystem/filesystem_error/cons.cc: Ensure that
        filesystem_error::what() contains system_error::what().

Tested x86_64-linux, committed to trunk. I'll backport to gcc-9-branch
too.

commit 026d1259cc4b761c4ab638ab2bcd251f880cbd32
Author: redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Thu Jun 27 09:42:39 2019 +0000

    PR libstdc++/91012 fixfilesystem_error::what() string
    
    When I refactored the filesystem_error code I changed it to only use the
    constructor parameter in the what() string, instead of the string
    returned by system_error::what(). That meant it no longer included the
    description of the error_code that system_error adds. This restores the
    previous behaivour, as encouraged by the standard ("Implementations
    should include the system_error::what() string and the pathnames of
    path1 and path2 in the native format in the returned string").
    
            PR libstdc++/91012
            * src/c++17/fs_path.cc (filesystem_error::_Impl): Use a string_view
            for the what_arg parameters.
            (filesystem_error::filesystem_error): Pass system_error::what() to
            the _Impl constructor.
            * testsuite/27_io/filesystem/filesystem_error/cons.cc: Ensure that
            filesystem_error::what() contains system_error::what().
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@272739 
138bc75d-0d04-0410-961f-82ee72b054a4

diff --git a/libstdc++-v3/src/c++17/fs_path.cc 
b/libstdc++-v3/src/c++17/fs_path.cc
index 82ac736f82a..14842452354 100644
--- a/libstdc++-v3/src/c++17/fs_path.cc
+++ b/libstdc++-v3/src/c++17/fs_path.cc
@@ -1928,20 +1928,20 @@ fs::hash_value(const path& p) noexcept
 
 struct fs::filesystem_error::_Impl
 {
-  _Impl(const string& what_arg, const path& p1, const path& p2)
+  _Impl(string_view what_arg, const path& p1, const path& p2)
   : path1(p1), path2(p2), what(make_what(what_arg, &p1, &p2))
   { }
 
-  _Impl(const string& what_arg, const path& p1)
+  _Impl(string_view what_arg, const path& p1)
   : path1(p1), path2(), what(make_what(what_arg, &p1, nullptr))
   { }
 
-  _Impl(const string& what_arg)
+  _Impl(string_view what_arg)
   : what(make_what(what_arg, nullptr, nullptr))
   { }
 
   static std::string
-  make_what(const std::string& s, const path* p1, const path* p2)
+  make_what(string_view s, const path* p1, const path* p2)
   {
     const std::string pstr1 = p1 ? p1->u8string() : std::string{};
     const std::string pstr2 = p2 ? p2->u8string() : std::string{};
@@ -1977,20 +1977,20 @@ template class std::__shared_ptr<const 
fs::filesystem_error::_Impl>;
 fs::filesystem_error::
 filesystem_error(const string& what_arg, error_code ec)
 : system_error(ec, what_arg),
-  _M_impl(std::__make_shared<_Impl>(what_arg))
+  _M_impl(std::__make_shared<_Impl>(system_error::what()))
 { }
 
 fs::filesystem_error::
 filesystem_error(const string& what_arg, const path& p1, error_code ec)
 : system_error(ec, what_arg),
-  _M_impl(std::__make_shared<_Impl>(what_arg, p1))
+  _M_impl(std::__make_shared<_Impl>(system_error::what(), p1))
 { }
 
 fs::filesystem_error::
 filesystem_error(const string& what_arg, const path& p1, const path& p2,
                 error_code ec)
 : system_error(ec, what_arg),
-  _M_impl(std::__make_shared<_Impl>(what_arg, p1, p2))
+  _M_impl(std::__make_shared<_Impl>(system_error::what(), p1, p2))
 { }
 
 fs::filesystem_error::~filesystem_error() = default;
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/filesystem_error/cons.cc 
b/libstdc++-v3/testsuite/27_io/filesystem/filesystem_error/cons.cc
index 8b24541cbc6..1644d355339 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/filesystem_error/cons.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/filesystem_error/cons.cc
@@ -36,9 +36,10 @@ test01()
   const std::error_code ec = make_error_code(std::errc::is_a_directory);
   const std::filesystem::path p1 = "test/path/one";
   const std::filesystem::path p2 = "/test/path/two";
+  std::system_error syserr(ec, str);
 
   const filesystem_error e1(str, ec);
-  VERIFY( contains(e1.what(), str) );
+  VERIFY( contains(e1.what(), syserr.what()) );
   VERIFY( !contains(e1.what(), "[]") ); // no "empty path" in the string
   VERIFY( e1.path1().empty() );
   VERIFY( e1.path2().empty() );
@@ -47,7 +48,7 @@ test01()
   const filesystem_error e2(str, p1, ec);
   VERIFY( e2.path1() == p1 );
   VERIFY( e2.path2().empty() );
-  VERIFY( contains(e2.what(), str) );
+  VERIFY( contains(e2.what(), syserr.what()) );
   VERIFY( contains(e2.what(), p1.string()) );
   VERIFY( !contains(e2.what(), "[]") );
   VERIFY( e2.code() == ec );
@@ -55,7 +56,7 @@ test01()
   const filesystem_error e3(str, std::filesystem::path{}, ec);
   VERIFY( e3.path1().empty() );
   VERIFY( e3.path2().empty() );
-  VERIFY( contains(e3.what(), str) );
+  VERIFY( contains(e3.what(), syserr.what()) );
   VERIFY( contains(e3.what(), "[]") );
   VERIFY( !contains(e3.what(), "[] []") );
   VERIFY( e3.code() == ec );
@@ -63,7 +64,7 @@ test01()
   const filesystem_error e4(str, p1, p2, ec);
   VERIFY( e4.path1() == p1 );
   VERIFY( e4.path2() == p2 );
-  VERIFY( contains(e4.what(), str) );
+  VERIFY( contains(e4.what(), syserr.what()) );
   VERIFY( contains(e4.what(), p1.string()) );
   VERIFY( contains(e4.what(), p2.string()) );
   VERIFY( !contains(e4.what(), "[]") );
@@ -72,7 +73,7 @@ test01()
   const filesystem_error e5(str, p1, std::filesystem::path{}, ec);
   VERIFY( e5.path1() == p1 );
   VERIFY( e5.path2().empty() );
-  VERIFY( contains(e5.what(), str) );
+  VERIFY( contains(e5.what(), syserr.what()) );
   VERIFY( contains(e5.what(), p1.string()) );
   VERIFY( contains(e5.what(), "[]") );
   VERIFY( e5.code() == ec );
@@ -80,7 +81,7 @@ test01()
   const filesystem_error e6(str, std::filesystem::path{}, p2, ec);
   VERIFY( e6.path1().empty() );
   VERIFY( e6.path2() == p2 );
-  VERIFY( contains(e6.what(), str) );
+  VERIFY( contains(e6.what(), syserr.what()) );
   VERIFY( contains(e6.what(), "[]") );
   VERIFY( contains(e6.what(), p2.string()) );
   VERIFY( e6.code() == ec );

Reply via email to