https://gcc.gnu.org/g:f7979b8bfa6542e6861f44c78d18cc1cf8dae4d6

commit r15-4978-gf7979b8bfa6542e6861f44c78d18cc1cf8dae4d6
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Mon Oct 28 17:55:02 2024 +0000

    libstdc++: Enable debug assertions for filesystem directory iterators
    
    Several member functions of filesystem::directory_iterator and
    filesystem::recursive_directory_iterator currently dereference their
    shared_ptr data member without checking for non-null. Because they use
    operator-> and that function only uses _GLIBCXX_DEBUG_PEDASSERT rather
    than __glibcxx_assert there is no assertion even when the library is
    built with _GLIBCXX_ASSERTIONS defined. This means that dereferencing
    invalid directory iterators gives an unhelpful segfault.
    
    By using (*p). instead of p-> we get an assertion when the library is
    built with _GLIBCXX_ASSERTIONS, with a "_M_get() != nullptr" message.
    
    libstdc++-v3/ChangeLog:
    
            * src/c++17/fs_dir.cc (fs::directory_iterator::operator*): Use
            shared_ptr::operator* instead of shared_ptr::operator->.
            (fs::recursive_directory_iterator::options): Likewise.
            (fs::recursive_directory_iterator::depth): Likewise.
            (fs::recursive_directory_iterator::recursion_pending): Likewise.
            (fs::recursive_directory_iterator::operator*): Likewise.
            (fs::recursive_directory_iterator::disable_recursion_pending):
            Likewise.

Diff:
---
 libstdc++-v3/src/c++17/fs_dir.cc | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/libstdc++-v3/src/c++17/fs_dir.cc b/libstdc++-v3/src/c++17/fs_dir.cc
index 28d27f6a9fa1..8fe9e5e4cc81 100644
--- a/libstdc++-v3/src/c++17/fs_dir.cc
+++ b/libstdc++-v3/src/c++17/fs_dir.cc
@@ -230,7 +230,7 @@ directory_iterator(const path& p, directory_options 
options, error_code* ecptr)
 const fs::directory_entry&
 fs::directory_iterator::operator*() const noexcept
 {
-  return _M_dir->entry;
+  return (*_M_dir).entry;
 }
 
 fs::directory_iterator&
@@ -327,25 +327,25 @@ 
fs::recursive_directory_iterator::~recursive_directory_iterator() = default;
 fs::directory_options
 fs::recursive_directory_iterator::options() const noexcept
 {
-  return _M_dirs->options;
+  return (*_M_dirs).options;
 }
 
 int
 fs::recursive_directory_iterator::depth() const noexcept
 {
-  return int(_M_dirs->size()) - 1;
+  return int((*_M_dirs).size()) - 1;
 }
 
 bool
 fs::recursive_directory_iterator::recursion_pending() const noexcept
 {
-  return _M_dirs->pending;
+  return (*_M_dirs).pending;
 }
 
 const fs::directory_entry&
 fs::recursive_directory_iterator::operator*() const noexcept
 {
-  return _M_dirs->top().entry;
+  return (*_M_dirs).top().entry;
 }
 
 fs::recursive_directory_iterator&
@@ -453,7 +453,7 @@ fs::recursive_directory_iterator::pop()
 void
 fs::recursive_directory_iterator::disable_recursion_pending() noexcept
 {
-  _M_dirs->pending = false;
+  (*_M_dirs).pending = false;
 }
 
 // Used to implement filesystem::remove_all.

Reply via email to