On Tue, 1 Feb 2022 at 22:00, Jonathan Wakely via Libstdc++ wrote: > > Tested powerpc64le-linux, pushed to trunk. > > > The standard requires directory iterators to become equal to the end > iterator value if they report an error. Some members functions of > filesystem::recursive_directory_iterator fail to do that. > > libstdc++-v3/ChangeLog: > > * src/c++17/fs_dir.cc (recursive_directory_iterator::increment): > Reset state to past-the-end iterator on error. > (fs::recursive_directory_iterator::pop(error_code&)): Likewise. > (fs::recursive_directory_iterator::pop()): Check _M_dirs before > it might get reset. > * src/filesystem/dir.cc (recursive_directory_iterator): Likewise, > for the TS implementation. > * testsuite/27_io/filesystem/iterators/error_reporting.cc: New test. > * testsuite/experimental/filesystem/iterators/error_reporting.cc: New test. > --- > libstdc++-v3/src/c++17/fs_dir.cc | 12 +- > libstdc++-v3/src/filesystem/dir.cc | 12 +- > .../filesystem/iterators/error_reporting.cc | 135 +++++++++++++++++ > .../filesystem/iterators/error_reporting.cc | 136 ++++++++++++++++++ > 4 files changed, 291 insertions(+), 4 deletions(-) > create mode 100644 libstdc++-v3/testsuite/27_io/filesystem/iterators/error_reporting.cc > create mode 100644 libstdc++-v3/testsuite/experimental/filesystem/iterators/error_reporting.cc > > diff --git a/libstdc++-v3/src/c++17/fs_dir.cc b/libstdc++-v3/src/c++17/fs_dir.cc > index e050304c19a..149a8b0740c 100644 > --- a/libstdc++-v3/src/c++17/fs_dir.cc > +++ b/libstdc++-v3/src/c++17/fs_dir.cc > @@ -311,6 +311,10 @@ fs::recursive_directory_iterator::increment(error_code& ec) > return *this; > } > } > + > + if (ec) > + _M_dirs.reset(); > + > return *this; > } > > @@ -334,16 +338,20 @@ fs::recursive_directory_iterator::pop(error_code& ec) > ec.clear(); > return; > } > - } while (!_M_dirs->top().advance(skip_permission_denied, ec)); > + } while (!_M_dirs->top().advance(skip_permission_denied, ec) && !ec); > + > + if (ec) > + _M_dirs.reset(); > } > > void > fs::recursive_directory_iterator::pop() > { > + const bool dereferenceable = _M_dirs != nullptr; > error_code ec; > pop(ec); > if (ec) > - _GLIBCXX_THROW_OR_ABORT(filesystem_error(_M_dirs > + _GLIBCXX_THROW_OR_ABORT(filesystem_error(dereferenceable > ? "recursive directory iterator cannot pop" > : "non-dereferenceable recursive directory iterator cannot pop", > ec)); This gives -Wunused warnings when libstdc++ is built with exceptions disabled. Fixed by the attached, pushed to trunk.