https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110952

--- Comment #4 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jonathan Wakely <r...@gcc.gnu.org>:

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

commit r15-5909-gf29d1b5836790ec795cb51bcfe25f7270b3e9f30
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Fri Nov 15 19:06:47 2024 +0000

    libstdc++: Add fancy pointer support to std::list [PR57272]

    Currently std::list uses raw pointers to connect its nodes, which is
    non-conforming. We should use the allocator's pointer type everywhere
    that a "pointer" is needed.

    Because the existing types like _List_node<T> are part of the ABI now,
    we can't change them. To support nodes that are connected by fancy
    pointers we need a parallel hierarchy of node types. This change
    introduces new class templates parameterized on the allocator's
    void_pointer type, __list::_Node_base and __list::_Node_header, and new
    class templates parameterized on the allocator's pointer type,
    __list::Node, __list::_Iterator. The iterator class template is used for
    both iterator and const_iterator. Whether std::list<T, A> should use the
    old _List_node<T> or new _list::_Node<A::pointer> type family internally
    is controlled by a new __list::_Node_traits traits template.

    Because std::pointer_traits and std::__to_address are not defined for
    C++98, there is no way to support fancy pointers in C++98. For C++98 the
    _Node_traits traits always choose the old _List_node family.

    In case anybody is currently using std::list with an allocator that has
    a fancy pointer, this change would be an ABI break, because their
    std::list instantiations would start to (correctly) use the fancy
    pointer type. If the fancy pointer just contains a single pointer and so
    has the same size, layout, and object represenation as a raw pointer,
    the code might still work (despite being an ODR violation). But if their
    fancy pointer has a different representation, they would need to
    recompile all their code using that allocator with std::list. Because
    std::list will never use fancy pointers in C++98 mode, recompiling
    everything to use fancy pointers isn't even possible if mixing C++98 and
    C++11 code that uses std::list. To alleviate this problem, compiling
    with -D_GLIBCXX_USE_ALLOC_PTR_FOR_LIST=0 will force std::list to have
    the old, non-conforming behaviour and use raw pointers internally. For
    testing purposes, compiling with -D_GLIBCXX_USE_ALLOC_PTR_FOR_LIST=9001
    will force std::list to always use the new node types.  This macro is
    currently undocumented, which needs to be fixed.

    The original _List_node<T> type is trivially constructible and trivially
    destructible, but the new __list::_Node<Ptr> type might not be,
    depending on the fancy pointer data members in _Node_base. This means
    that std::list needs to explicitly construct and destroy the node
    object, not just the value that it contains. This commit adds a new
    __allocated_obj helper which wraps an __allocated_ptr and additionally
    constructs and destroys an object in the allocated storage.

    Pretty printers for std::list need to be updated to handle the new node
    types. Potentially we just can't pretty print them, because we don't
    know how to follow the fancy pointers to traverse the list.

    libstdc++-v3/ChangeLog:

            PR libstdc++/57272
            PR libstdc++/110952
            * include/bits/allocated_ptr.h (__allocated_ptr::get): Add
            const.
            (__allocated_ptr::operator bool, __allocated_ptr::release): New
            member functions.
            (__allocate_guarded): Add inline.
            (__allocated_obj): New class template.
            (__allocate_guarded_obj): New function template.
            * include/bits/list.tcc (_List_base::_M_clear()): Replace uses
            of raw pointers. Use _M_destroy_node.
            (list::emplace, list::insert): Likewise.
            (list::sort): Adjust check for 0 or 1 wsize. Use template
            argument list for _Scratch_list.
            * include/bits/stl_list.h (_GLIBCXX_USE_ALLOC_PTR_FOR_LIST):
            Define.
            (_List_node_base::_Base_ptr): New typedef.
            (_List_node_base::_M_base): New member functions.
            (_List_node_header::_M_base): Make public and add
            using-declaration for base class overload.
            (__list::_Node_traits, __list::_Node_base)
            (__list::_Node_header, __list::_Node, __list::_Iterator): New
            class templates.
            (_Scratch_list): Turn class into class template. Use _Base_ptr
            typedef instead of _List_node_base*.
            (_List_node::_Node_ptr): New typedef.
            (_List_node::_M_node_ptr): New member function.
            (_List_base, _List_impl): Use _Node_traits to get node types.
            (_List_base::_M_put_node): Convert to fancy pointer if needed.
            (_List_base::_M_destroy_node): New member function.
            (_List_base(_List_base&&, _Node_alloc_type&&)): Use if constexpr
            to make function a no-op for fancy pointers.
            (_List_base::_S_distance, _List_base::_M_distance)
            (_List_base::_M_node_count): Likewise.
            (list): Use _Node_traits to get iterator, node and pointer
            types.
            (list::_M_create_node): Use _Node_ptr typedef instead of _Node*.
            Use __allocate_guarded_obj instead of _M_get_node.
            (list::end, list::cend, list::empty): Use node header's
            _M_base() function instead of taking its address.
            (list::swap): Use _Node_traits to get node base type.
            (list::_M_create_node, list::_M_insert): Use _Node_ptr instead
            of _Node*.
            (list::_M_erase): Likewise. Use _M_destroy_node.
            (__distance): Overload for __list::_Iterator.
            (_Node_base::swap, _Node_base::_M_transfer): Define non-inline
            member functions of class templates.
            (_Node_header::_M_reverse): Likewise.
            * testsuite/23_containers/list/capacity/29134.cc: Check max_size
            for allocator of new node type.
            * testsuite/23_containers/list/capacity/node_sizes.cc: New test.
            *
testsuite/23_containers/list/requirements/explicit_instantiation/alloc_ptr.cc:
            New test.
            *
testsuite/23_containers/list/requirements/explicit_instantiation/alloc_ptr_ignored.cc:
            New test.
  • [Bug libstdc++/110952] Allocato... cvs-commit at gcc dot gnu.org via Gcc-bugs

Reply via email to