LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 50224 - std::forward_list::swap noexcept specification not using correct member type
Summary: std::forward_list::swap noexcept specification not using correct member type
Status: RESOLVED FIXED
Alias: None
Product: libc++
Classification: Unclassified
Component: All Bugs (show other bugs)
Version: 12.0
Hardware: PC Linux
: P enhancement
Assignee: Hyundeok Park
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-05-04 23:44 PDT by Hyundeok Park
Modified: 2021-06-22 09:42 PDT (History)
3 users (show)

See Also:
Fixed By Commit(s): 7adf713a5e22b44c7cc746bcd379d844277a19f2


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Hyundeok Park 2021-05-04 23:44:56 PDT
The current implementation of `std::forward_list::swap` is as follows:

```cpp
_LIBCPP_INLINE_VISIBILITY
    void swap(__forward_list_base& __x)
#if _LIBCPP_STD_VER >= 14
        _NOEXCEPT;
#else
        _NOEXCEPT_(!__node_traits::propagate_on_container_move_assignment::value ||
                    __is_nothrow_swappable<__node_allocator>::value);
```

which uses `propagate_on_container_move_assignment` for `noexcept` specification.

This must use `propagate_on_container_swap` for checking according to [[container.requirements.general/8]](http://eel.is/c++draft/container.requirements.general#8).

When the change is applied, the declaration should look like:

```cpp
_LIBCPP_INLINE_VISIBILITY
    void swap(__forward_list_base& __x)
#if _LIBCPP_STD_VER >= 14
        _NOEXCEPT;
#else
        _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
                    __is_nothrow_swappable<__node_allocator>::value);
```

and the definition should be as follows:

```cpp
template <class _Tp, class _Alloc>
inline
void
__forward_list_base<_Tp, _Alloc>::swap(__forward_list_base& __x)
#if _LIBCPP_STD_VER >= 14
        _NOEXCEPT
#else
        _NOEXCEPT_(!__node_traits::propagate_on_container_swap::value ||
                    __is_nothrow_swappable<__node_allocator>::value)
#endif
{
    _VSTD::__swap_allocator(__alloc(), __x.__alloc(),
            integral_constant<bool, __node_traits::propagate_on_container_swap::value>());
    using _VSTD::swap;
    swap(__before_begin()->__next_, __x.__before_begin()->__next_);
}
```
Comment 1 Louis Dionne 2021-06-22 09:42:41 PDT
Thanks for the fix!

commit 7adf713a5e22b44c7cc746bcd379d844277a19f2
Author: Hyundeok Park <p.hyundeok76@gmail.com>
Date:   Tue Jun 22 12:37:51 2021 -0400

    [libc++] Change forward_list::swap to use propagate_on_container_swap for noexcept specification

    The current implementation of `std::forward_list::swap` uses
    `propagate_on_container_move_assignment` for `noexcept` specification.
    This patch changes it to use `propagate_on_container_swap`, as it should.

    Fixes https://llvm.org/PR50224.

    Differential Revision: https://reviews.llvm.org/D101899