diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index f30fedf2948..36fcab95d7b 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,13 @@ +2019-01-30 Jonathan Wakely + + PR libstdc++/89117 + * src/c++17/fs_path.cc (path::replace_extension): Erase extension from + final component as well as from _M_pathname. Append the dot using + operator+= instead of only to _M_pathname. + (path::_M_find_extension): Reformat slightly. + * testsuite/27_io/filesystem/path/modifiers/replace_extension.cc: + Add more test cases. + 2019-01-30 Ulrich Drepper * doc/xml/manual/status_cxx2020.xml: Update P0600 entry. diff --git a/libstdc++-v3/src/c++17/fs_path.cc b/libstdc++-v3/src/c++17/fs_path.cc index 34de52f3a0f..db6a1cb29d8 100644 --- a/libstdc++-v3/src/c++17/fs_path.cc +++ b/libstdc++-v3/src/c++17/fs_path.cc @@ -1258,17 +1258,16 @@ path::replace_extension(const path& replacement) _M_pathname.erase(ext.second); else { - const auto& back = _M_cmpts.back(); - if (ext.first != &back._M_pathname) - _GLIBCXX_THROW_OR_ABORT( - std::logic_error("path::replace_extension failed")); + auto& back = _M_cmpts.back(); + __glibcxx_assert( ext.first == &back._M_pathname ); + back._M_pathname.erase(ext.second); _M_pathname.erase(back._M_pos + ext.second); } } // If replacement is not empty and does not begin with a dot character, // a dot character is appended if (!replacement.empty() && replacement.native()[0] != dot) - _M_pathname += dot; + operator+=("."); operator+=(replacement); return *this; } @@ -1803,8 +1802,9 @@ path::_M_find_extension() const { if (sz <= 2 && (*s)[0] == dot) return { s, string_type::npos }; - const auto pos = s->rfind(dot); - return { s, pos ? pos : string_type::npos }; + if (const auto pos = s->rfind(dot)) + return { s , pos }; + return { s, string_type::npos }; } } return {}; diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/modifiers/replace_extension.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/modifiers/replace_extension.cc index df4b77aa116..98f2e6e4c41 100644 --- a/libstdc++-v3/testsuite/27_io/filesystem/path/modifiers/replace_extension.cc +++ b/libstdc++-v3/testsuite/27_io/filesystem/path/modifiers/replace_extension.cc @@ -33,6 +33,15 @@ test01() compare_paths( path("/foo.txt").replace_extension("cpp"), "/foo.cpp" ); compare_paths( path("/foo.txt").replace_extension(".cpp"), "/foo.cpp" ); compare_paths( path("/").replace_extension("bar"), "/.bar" ); + compare_paths( path("/").replace_extension(".bar"), "/.bar" ); + compare_paths( path("/dir/").replace_extension("bar"), "/dir/.bar" ); + compare_paths( path("dir/foo").replace_extension("bar"), "dir/foo.bar" ); + + // PR 89117: + compare_paths( path("/foo.txt").replace_extension(), "/foo" ); + compare_paths( path("foo.txt").replace_extension(), "foo" ); + compare_paths( path("/foo").replace_extension(), "/foo" ); + compare_paths( path("foo").replace_extension(), "foo" ); } void