https://gcc.gnu.org/g:2af87d98e66e57d51f36220de983eff44bae98c8

commit r15-3653-g2af87d98e66e57d51f36220de983eff44bae98c8
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Wed Sep 4 21:31:58 2024 +0100

    libstdc++: Adjust std::span::iterator to be ADL-proof
    
    Because std::span<Incomplete> can be useful, it makes sense to define
    std::span<Incomplete>::iterator such that Incomplete is not an
    associated class, and so the compiler won't attempt to complete it when
    doing ADL for span iterators (including during the definition of
    std::span<Incomplete>::const_iterator which checks that iterator
    satisfies std::input_or_output_iterator).
    
    We can't make this change for std::vector<Incomplete> because it would
    change the mangled name of std::vector<Incomplete>::iterator which would
    affect the mangled names of templates and functions written by users.
    
    We can do the same thing for std::basic_stacktrace<Alloc> just so that
    Alloc is not an associated class. This is probably less beneficial, as
    Alloc can't be incomplete, and using SomeAllocator<Incomplete> as the
    allocator parameter doesn't seem useful. But simply making the
    stacktrace iterator not use Alloc for ADL lookup seems worthwhile. This
    is doable because std::stacktrace is part of C++23 so its ABI isn't
    considered stable yet.
    
    libstdc++-v3/ChangeLog:
    
            * include/std/span (span::__iter_tag): Declare nested type.
            (span::iterator): Use __iter_tag as second template argument.
            * include/std/stacktrace (basic_stacktrace::iterator): Use _Impl
            as second template argument.

Diff:
---
 libstdc++-v3/include/std/span       | 5 ++++-
 libstdc++-v3/include/std/stacktrace | 4 +++-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/std/span b/libstdc++-v3/include/std/span
index 00fc52791526..b7392a0500e9 100644
--- a/libstdc++-v3/include/std/span
+++ b/libstdc++-v3/include/std/span
@@ -123,6 +123,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        using __is_compatible_ref
          = __is_array_convertible<_Type, remove_reference_t<_Ref>>;
 
+      // Nested type so that _Type is not an associated class of iterator.
+      struct __iter_tag;
+
     public:
       // member types
       using element_type           = _Type;
@@ -133,7 +136,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       using const_pointer          = const _Type*;
       using reference              = element_type&;
       using const_reference        = const element_type&;
-      using iterator = __gnu_cxx::__normal_iterator<pointer, span>;
+      using iterator = __gnu_cxx::__normal_iterator<pointer, __iter_tag>;
       using reverse_iterator       = std::reverse_iterator<iterator>;
 #if __cplusplus > 202002L
       using const_iterator         = std::const_iterator<iterator>;
diff --git a/libstdc++-v3/include/std/stacktrace 
b/libstdc++-v3/include/std/stacktrace
index cd2606257fec..cdd1276d2124 100644
--- a/libstdc++-v3/include/std/stacktrace
+++ b/libstdc++-v3/include/std/stacktrace
@@ -179,13 +179,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     {
       using _AllocTraits = allocator_traits<_Allocator>;
       using uintptr_t = __UINTPTR_TYPE__;
+      struct _Impl;
 
     public:
       using value_type = stacktrace_entry;
       using const_reference = const value_type&;
       using reference = value_type&;
       using const_iterator
-       = __gnu_cxx::__normal_iterator<value_type*, basic_stacktrace>;
+       = __gnu_cxx::__normal_iterator<typename _AllocTraits::const_pointer,
+                                      _Impl>;
       using iterator = const_iterator;
       using reverse_iterator = std::reverse_iterator<iterator>;
       using const_reverse_iterator = std::reverse_iterator<const_iterator>;

Reply via email to