diff --git a/libstdc++-v3/src/c++17/fs_path.cc b/libstdc++-v3/src/c++17/fs_path.cc index 2d9e29d9e7a3f82296a6b6aec2673c8cf4c34cc1..506ff25f9a6db19ad8062a224c07c61e19f31f22 100644 --- a/libstdc++-v3/src/c++17/fs_path.cc +++ b/libstdc++-v3/src/c++17/fs_path.cc @@ -1907,10 +1907,9 @@ path::_M_split_cmpts() _M_cmpts.type(_Type::_Multi); _M_cmpts.reserve(_M_cmpts.size() + buf.size()); auto output = _M_cmpts._M_impl->end(); - for (auto& c : buf) + for (const auto& c : buf) { - auto pos = c.str.data() - _M_pathname.data(); - ::new(output++) _Cmpt(c.str, c.type, pos); + ::new(output++) _Cmpt(c.str, c.type, parser.offset(c)); ++_M_cmpts._M_impl->_M_size; } next = buf.begin(); @@ -1930,9 +1929,8 @@ path::_M_split_cmpts() auto output = _M_cmpts._M_impl->end(); for (int i = 0; i < n; ++i) { - auto c = buf[i]; - auto pos = c.str.data() - _M_pathname.data(); - ::new(output++) _Cmpt(c.str, c.type, pos); + const auto& c = buf[i]; + ::new(output++) _Cmpt(c.str, c.type, parser.offset(c)); ++_M_cmpts._M_impl->_M_size; } } diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/decompose/parent_path.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/decompose/parent_path.cc index 84e86ec7a1958d293533871a0fa2856bddcffcd9..b6ca525bc82c3e23805d3fa831dc2eaaaee38ab3 100644 --- a/libstdc++-v3/testsuite/27_io/filesystem/path/decompose/parent_path.cc +++ b/libstdc++-v3/testsuite/27_io/filesystem/path/decompose/parent_path.cc @@ -18,7 +18,7 @@ // with this library; see the file COPYING3. If not see // <http://www.gnu.org/licenses/>. -// 8.4.9 path decomposition [path.decompose] +// C++17 30.10.8.4.9 path decomposition [fs.path.decompose] #include <filesystem> #include <testsuite_hooks.h> @@ -64,9 +64,32 @@ test02() } } +void +test03() +{ + const std::string narrow = "there/are/no/wrong/turns/only/unexpected/paths"; + const path::string_type s(narrow.begin(), narrow.end()); + const auto s1 = s.substr(0, s.length() - 6); // remove "/paths" + const auto s2 = s1.substr(0, s1.length() - 16); // remove "/only/..." + + // PR libstdc++/99805 + path p = path::string_type(s); + auto pp = p.parent_path(); + VERIFY( pp.native() == s1 ); + pp = pp.parent_path().parent_path(); + VERIFY( pp.native() == s2 ); + + path from_lval(s); + pp = from_lval.parent_path(); + VERIFY( pp.native() == s1 ); + pp = pp.parent_path().parent_path(); + VERIFY( pp.native() == s2 ); +} + int main() { test01(); test02(); + test03(); }