[1/2] libstdc++: Enable debug assertions for filesystem directory iterators
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_gcc_build--master-arm |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 |
success
|
Build passed
|
Commit Message
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.
---
Tested x86_64-linux.
Also available for review at:
https://forge.sourceware.org/gcc/gcc-TEST/pulls/13
libstdc++-v3/src/c++17/fs_dir.cc | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
Comments
Pushed
On Thu, 31 Oct 2024 at 20:06, Jonathan Wakely <jwakely@redhat.com> wrote:
>
> 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.
> ---
> Tested x86_64-linux.
>
> Also available for review at:
> https://forge.sourceware.org/gcc/gcc-TEST/pulls/13
>
>
> 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 28d27f6a9fa..8fe9e5e4cc8 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.
> --
> 2.47.0
>
@@ -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.