From e11c48711128a8aff3938cf28954acf1b1cc0b62 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Thu, 27 Jun 2019 10:42:39 +0100 Subject: [PATCH] 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(). From-SVN: r272739 --- libstdc++-v3/ChangeLog | 10 ++++++++++ libstdc++-v3/src/c++17/fs_path.cc | 14 +++++++------- .../27_io/filesystem/filesystem_error/cons.cc | 13 +++++++------ 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 29502215816..fd823af319a 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,13 @@ +2019-06-27 Jonathan Wakely + + 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(). + 2019-06-26 Jonathan Wakely * include/std/charconv (chars_format): Define bitmask type. 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; 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 ); -- 2.30.2