summaryrefslogtreecommitdiff
path: root/libstdc++-v3/include
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2019-01-04 14:03:59 +0000
committerJonathan Wakely <redi@gcc.gnu.org>2019-01-04 14:03:59 +0000
commit73d968d94561fd521bc6a9af993ed1d1ebba8459 (patch)
tree367ab721427f3648ac6801f1673f52a761409aa1 /libstdc++-v3/include
parent2d4c371efa1451279764e9768d7efa2edfa02e59 (diff)
downloadgcc-73d968d94561fd521bc6a9af993ed1d1ebba8459.tar.gz
Fix bugs in filesystem::path::lexically_normal()
Using path::_List::erase(const_iterator) to remove a non-final component in path::lexically_normal() is a bug, because it leaves the following component with an incorrect _M_pos value. Instead of providing erase members that allow removing components from the middle, replace them with pop_back() and _M_erase_from(const_iterator) which only allow removing elements at the end. Most uses of erase are unaffected, because they only remove elements from the end anyway. The one use of erasure from the middle in lexically_normal() is replaced by calls to pop_back() and/or clearing the last component to leave it as an empty final filename. Also replace the "???" comment in lexically_normal() to document when that branch is taken. * include/bits/fs_path.h (path::_List::erase): Replace both overloads with ... (path::pop_back(), path::_M_erase_from(const_iterator)): New member functions that will only erase elements at the end. * src/filesystem/std-path.cc (path::_List::_Impl::pop_back()): Define. (path::_List::_Impl::_M_erase_from(const_iterator)): Define. (path::_List::operator=(const _List&)): Use _M_erase_from(p) instead of erase(p, end()). (path::_List::pop_back()): Define. (path::_List::_M_erase_from(const_iterator)): Define. (path::operator/=(const path&)): Use pop_back to remove last component and _M_erase_from to remove multiple components. (path::_M_append(basic_string_view<value_type>)): Likewise. (path::operator+=(const path&)): Likewise. (path::_M_concat(basic_string_view<value_type>)): Likewise. (path::remove_filename()): Likewise. (path::lexically_normal()): Use _List::_Impl iterators instead of path::iterator. Use pop_back to remove components from the end. Clear trailing filename, instead of using erase(const_iterator) to remove a non-final component. * testsuite/27_io/filesystem/path/generation/normal.cc: Test additional cases. * testsuite/27_io/filesystem/path/generation/normal2.cc: New test. From-SVN: r267576
Diffstat (limited to 'libstdc++-v3/include')
-rw-r--r--libstdc++-v3/include/bits/fs_path.h4
1 files changed, 2 insertions, 2 deletions
diff --git a/libstdc++-v3/include/bits/fs_path.h b/libstdc++-v3/include/bits/fs_path.h
index 69af50a19f8..34a5d324ce0 100644
--- a/libstdc++-v3/include/bits/fs_path.h
+++ b/libstdc++-v3/include/bits/fs_path.h
@@ -544,8 +544,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
const value_type& front() const noexcept;
const value_type& back() const noexcept;
- void erase(const_iterator);
- void erase(const_iterator, const_iterator);
+ void pop_back();
+ void _M_erase_from(const_iterator __pos); // erases [__pos,end())
struct _Impl;
struct _Impl_deleter