Hello,The attached patch fixes a compile error when converting a weak_ptr of array type to a compatible type, for instance:
std::weak_ptr<int [42]> wptr; std::weak_ptr<int []> wptr2 = wptr; // ERROR https://gcc.godbolt.org/z/EWYb73MvfThe reason seems to be a typo: the inner __weak_ptr class has a lock() implementation which doesn't work with arrays because it accidentally uses `element_type` instead of `_Tp`. That lock() (and *not* std::weak_ptr::lock(), which is instead fine) is called by the converting constructors of __weak_ptr and that causes the compile error.
I'm not sure if this has been already reported somewhere. Tested on x86-64 Linux. Thanks, -- Giuseppe D'Angelo
From 2636a2be91fe5a82472068121382a569e0676865 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo <giuseppe.dang...@kdab.com> Date: Tue, 10 Dec 2024 00:56:13 +0100 Subject: [PATCH] libstdc++: fix compile error when converting std::weak_ptr<T[]> A std::weak_ptr<T[]> can be converted to a compatible std::weak_ptr<U[]>. This is implemented by having suitable converting constructors to std::weak_ptr which dispatch to the __weak_ptr base class (implementation detail). In __weak_ptr<T[]>, lock() is supposed to return a __shared_ptr<T[]>, not a __shared_ptr<element_type> (that is, __shared_ptr<T>). Unfortunately the return type of lock() and the type of the returned __shared_ptr were mismatching and that was causing a compile error: when converting a __weak_ptr<T[]> to a __weak_ptr<U[]> through a converting constructor, the code calls lock(), and that simply failed to build. Fix it by removing the usage of element_type inside lock(), and using _Tp instead. Note that std::weak_ptr::lock() itself was already correct; the one in __weak_ptr was faulty (and that is the one called by __weak_ptr's converting constructors). libstdc++-v3/ChangeLog: * include/bits/shared_ptr_base.h: Fixed a compile error when calling lock() on a weak_ptr<T[]>, by removing an erroneous usage of element_type from within lock(). * testsuite/20_util/shared_ptr/requirements/explicit_instantiation/1.cc: Add more tests for array types. * testsuite/20_util/weak_ptr/requirements/explicit_instantiation/1.cc: Likewise. * testsuite/20_util/shared_ptr/requirements/1.cc: New test. * testsuite/20_util/weak_ptr/requirements/1.cc: New test. Signed-off-by: Giuseppe D'Angelo <giuseppe.dang...@kdab.com> --- libstdc++-v3/include/bits/shared_ptr_base.h | 2 +- .../20_util/shared_ptr/requirements/1.cc | 33 +++++++++++++++++++ .../requirements/explicit_instantiation/1.cc | 12 +++++++ .../20_util/weak_ptr/requirements/1.cc | 33 +++++++++++++++++++ .../requirements/explicit_instantiation/1.cc | 12 +++++++ 5 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 libstdc++-v3/testsuite/20_util/shared_ptr/requirements/1.cc create mode 100644 libstdc++-v3/testsuite/20_util/weak_ptr/requirements/1.cc diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index ee01594ce0c..bc87c402afb 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -2076,7 +2076,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __shared_ptr<_Tp, _Lp> lock() const noexcept - { return __shared_ptr<element_type, _Lp>(*this, std::nothrow); } + { return __shared_ptr<_Tp, _Lp>(*this, std::nothrow); } long use_count() const noexcept diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/1.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/1.cc new file mode 100644 index 00000000000..8ddb5d220ac --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/1.cc @@ -0,0 +1,33 @@ +// { dg-do compile { target c++11 } } +// { dg-require-effective-target hosted } + +#include <memory> +#include <testsuite_tr1.h> + +using namespace __gnu_test; + +void +test01() +{ + std::shared_ptr<ClassType> ptr; + std::shared_ptr<const ClassType> ptr2 = ptr; + +#if __cpp_lib_shared_ptr_arrays >= 201611L + std::shared_ptr<ClassType[10]> ptr_array; + std::shared_ptr<ClassType[]> ptr_array2 = ptr_array; + std::shared_ptr<ClassType const []> ptr_array3 = ptr_array; +#endif +} + +void +test02() +{ + std::shared_ptr<IncompleteClass> ptr; + std::shared_ptr<const IncompleteClass> ptr2 = ptr; + +#if __cpp_lib_shared_ptr_arrays >= 201611L + std::shared_ptr<IncompleteClass[10]> ptr_array; + std::shared_ptr<IncompleteClass[]> ptr_array2 = ptr_array; + std::shared_ptr<IncompleteClass const []> ptr_array3 = ptr_array; +#endif +} diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation/1.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation/1.cc index 94bc8c7adfe..48f162d4072 100644 --- a/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation/1.cc +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/requirements/explicit_instantiation/1.cc @@ -28,3 +28,15 @@ template class std::shared_ptr<int>; template class std::shared_ptr<void>; template class std::shared_ptr<ClassType>; template class std::shared_ptr<IncompleteClass>; + +#if __cpp_lib_shared_ptr_arrays >= 201611L +template class std::shared_ptr<ClassType []>; +template class std::shared_ptr<ClassType [42]>; +template class std::shared_ptr<ClassType const []>; +template class std::shared_ptr<ClassType const [42]>; + +template class std::shared_ptr<IncompleteClass []>; +template class std::shared_ptr<IncompleteClass [42]>; +template class std::shared_ptr<IncompleteClass const []>; +template class std::shared_ptr<IncompleteClass const [42]>; +#endif diff --git a/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/1.cc b/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/1.cc new file mode 100644 index 00000000000..04ea837d85a --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/1.cc @@ -0,0 +1,33 @@ +// { dg-do compile { target c++11 } } +// { dg-require-effective-target hosted } + +#include <memory> +#include <testsuite_tr1.h> + +using namespace __gnu_test; + +void +test01() +{ + std::weak_ptr<ClassType> ptr; + std::weak_ptr<const ClassType> ptr2 = ptr; + +#if __cpp_lib_shared_ptr_arrays >= 201611L + std::weak_ptr<ClassType[10]> ptr_array; + std::weak_ptr<ClassType[]> ptr_array2 = ptr_array; + std::weak_ptr<ClassType const []> ptr_array3 = ptr_array; +#endif +} + +void +test02() +{ + std::weak_ptr<IncompleteClass> ptr; + std::weak_ptr<const IncompleteClass> ptr2 = ptr; + +#if __cpp_lib_shared_ptr_arrays >= 201611L + std::weak_ptr<IncompleteClass[10]> ptr_array; + std::weak_ptr<IncompleteClass[]> ptr_array2 = ptr_array; + std::weak_ptr<IncompleteClass const []> ptr_array3 = ptr_array; +#endif +} diff --git a/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation/1.cc b/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation/1.cc index b32ff6ea284..b51a614693c 100644 --- a/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation/1.cc +++ b/libstdc++-v3/testsuite/20_util/weak_ptr/requirements/explicit_instantiation/1.cc @@ -28,3 +28,15 @@ template class std::weak_ptr<int>; template class std::weak_ptr<void>; template class std::weak_ptr<ClassType>; template class std::weak_ptr<IncompleteClass>; + +#if __cpp_lib_shared_ptr_arrays >= 201611L +template class std::weak_ptr<ClassType []>; +template class std::weak_ptr<ClassType [42]>; +template class std::weak_ptr<ClassType const []>; +template class std::weak_ptr<ClassType const [42]>; + +template class std::weak_ptr<IncompleteClass []>; +template class std::weak_ptr<IncompleteClass [42]>; +template class std::weak_ptr<IncompleteClass const []>; +template class std::weak_ptr<IncompleteClass const [42]>; +#endif -- 2.34.1
smime.p7s
Description: S/MIME Cryptographic Signature