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

            Bug ID: 120561
           Summary: std::weak_ptr<T[N]> cannot be converted to
                    std::weak_ptr<T[]> or std::weak_ptr<void>, and
                    std::weak_ptr<T[]> cannot be converted to
                    std::weak_ptr<void>
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: leekillough at gmail dot com
  Target Milestone: ---

std::weak_ptr<T[N]> cannot be converted to std::weak_ptr<T[ ]>.
std::weak_ptr<T[N]> cannot be converted to std::weak_ptr<void>.
std::weak_ptr<T[ ]> cannot be converted to std::weak_ptr<void>.

#include<memory>
std::weak_ptr<int[1]> p1;
std::weak_ptr<int[ ]> p2;
std::weak_ptr<int[ ]> w1 = p1;
std::weak_ptr<void  > w2 = p1;
std::weak_ptr<void  > w3 = p2;

Spurious errors occur in std::weak_ptr<T>::lock() trying to nothrow-construct
std::shared_ptr<element_type> from std::weak_ptr<T> when T is an array, even
though std::weak_ptr<T>::lock() is not needed for std::weak_ptr<T>
construction.

> /usr/include/c++/13/bits/shared_ptr_base.h:2068:16: error: no matching 
> function for call to ‘std::__shared_ptr<int, > 
> __gnu_cxx::_S_atomic>::__shared_ptr(const std::__weak_ptr<int [], 
> __gnu_cxx::_S_atomic>&, const std::nothrow_t&)’
> 2068 |       { return __shared_ptr<element_type, _Lp>(*this, std::nothrow); }
>      |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Prior to C++17, element_type = T. In C++17 and later, element_type =
std::remove_extent_t<T>.

When converting from std::weak_ptr<T> to std::weak_ptr<U> where T is array and
T != U, std::weak_ptr<T>::lock() tries to nothrow-construct
std::shared_ptr<element_type> from std::weak_ptr<T>. It is exactly the error
produced by the code:

#include<memory>
template<class T>
struct weak_ptr : std::weak_ptr<T> {
    auto lock() {
        return std::shared_ptr<typename std::weak_ptr<T>::element_type>(*this); 
    }
};
template struct weak_ptr<int[ ]>;
template struct weak_ptr<int[1]>;

It seems like a pre-C++17 implementation of std::weak_ptr<T>::lock() which
assumes that element_type = T, is triggered by std::weak_ptr<T>::weak_ptr(const
std::weak_ptr<U>&) when T is an array and T != U.

These errors do not occur when converting from std::shared_ptr<T> to
std::weak_ptr<U> where T is an array and T != U, and std::weak_ptr<T>::lock()
otherwise works when T is an array.

This occurs on almost all versions except trunk, but I cannot see this reported
or confirmed fixed. Recording this in case others find the same error.

Reply via email to