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

commit r15-8048-gdf0e6509bf74421ea68a2e025300bcd6ca63722f
Author: Giuseppe D'Angelo <giuseppe.dang...@kdab.com>
Date:   Tue Dec 10 00:56:13 2024 +0100

    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 __weak_ptr's
    converting constructor, the code calls lock(), and that simply fails 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 (lock): 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.

Diff:
---
 libstdc++-v3/include/bits/shared_ptr_base.h        |  2 +-
 .../testsuite/20_util/shared_ptr/requirements/1.cc | 33 ++++++++++++++++++++++
 .../requirements/explicit_instantiation/1.cc       | 12 ++++++++
 .../testsuite/20_util/weak_ptr/requirements/1.cc   | 33 ++++++++++++++++++++++
 .../requirements/explicit_instantiation/1.cc       | 12 ++++++++
 5 files changed, 91 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h 
b/libstdc++-v3/include/bits/shared_ptr_base.h
index 053857b4c29f..3622e0291178 100644
--- a/libstdc++-v3/include/bits/shared_ptr_base.h
+++ b/libstdc++-v3/include/bits/shared_ptr_base.h
@@ -2075,7 +2075,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 000000000000..8ddb5d220ac7
--- /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 6418e0c4bc7c..3bd05c36f8fc 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 000000000000..04ea837d85a7
--- /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 b2704d659db4..24d16ef0e566 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

Reply via email to