public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug libstdc++/116529] New: Construction of unique_ptr with reference type is rejected because of auto_ptr constructor
@ 2024-08-29  6:24 luigighiron at gmail dot com
  2024-08-29 10:17 ` [Bug libstdc++/116529] " redi at gcc dot gnu.org
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: luigighiron at gmail dot com @ 2024-08-29  6:24 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 116529
           Summary: Construction of unique_ptr with reference type is
                    rejected because of auto_ptr constructor
           Product: gcc
           Version: 15.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: luigighiron at gmail dot com
  Target Milestone: ---

When constructing a unique_ptr with a reference type an error will occur in the
libstdc++ implementation due to the auto_ptr constructor attempting to form a
pointer to the reference type. For example:

#include<memory>
int main(){
    struct deleter{
        using pointer=int*;
        void operator()(pointer p)const{
            delete p;
        }
    };
    std::unique_ptr<int&,deleter>u(new int);
}

libstdc++ rejects this program, libc++ and MSVC's STL allow it (when compiling
with C++17 or newer). The auto_ptr constructor was removed in C++17 along with
the rest of auto_ptr, this means that there shouldn't be any restrictions on
using a reference type when constructing a unique_ptr. I haven't seen any
restrictions on using a unique_ptr with a reference type so I assume that this
is OK (since C++17).

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/116529] Construction of unique_ptr with reference type is rejected because of auto_ptr constructor
  2024-08-29  6:24 [Bug libstdc++/116529] New: Construction of unique_ptr with reference type is rejected because of auto_ptr constructor luigighiron at gmail dot com
@ 2024-08-29 10:17 ` redi at gcc dot gnu.org
  2024-08-29 10:22 ` redi at gcc dot gnu.org
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: redi at gcc dot gnu.org @ 2024-08-29 10:17 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
-D_GLIBCXX_USE_DEPRECATED=0 allows it to compile

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/116529] Construction of unique_ptr with reference type is rejected because of auto_ptr constructor
  2024-08-29  6:24 [Bug libstdc++/116529] New: Construction of unique_ptr with reference type is rejected because of auto_ptr constructor luigighiron at gmail dot com
  2024-08-29 10:17 ` [Bug libstdc++/116529] " redi at gcc dot gnu.org
@ 2024-08-29 10:22 ` redi at gcc dot gnu.org
  2024-08-29 10:24 ` redi at gcc dot gnu.org
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: redi at gcc dot gnu.org @ 2024-08-29 10:22 UTC (permalink / raw)
  To: gcc-bugs

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

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|                            |2024-08-29
           Keywords|                            |rejects-valid
             Status|UNCONFIRMED                 |NEW
     Ever confirmed|0                           |1

--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
And this fixes it:

diff --git a/libstdc++-v3/include/backward/auto_ptr.h
b/libstdc++-v3/include/backward/auto_ptr.h
index 271a64d1de0..9e1318a9d9d 100644
--- a/libstdc++-v3/include/backward/auto_ptr.h
+++ b/libstdc++-v3/include/backward/auto_ptr.h
@@ -329,7 +329,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif // HOSTED

   template<typename _Tp, typename _Dp>
-  template<typename _Up, typename>
+  template<typename _Up, typename, typename>
     inline
     unique_ptr<_Tp, _Dp>::unique_ptr(auto_ptr<_Up>&& __u) noexcept
     : _M_t(__u.release(), deleter_type()) { }
diff --git a/libstdc++-v3/include/bits/unique_ptr.h
b/libstdc++-v3/include/bits/unique_ptr.h
index 0f600db32f9..167136fe890 100644
--- a/libstdc++-v3/include/bits/unique_ptr.h
+++ b/libstdc++-v3/include/bits/unique_ptr.h
@@ -379,8 +379,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
       /// Converting constructor from @c auto_ptr
-      template<typename _Up, typename = _Require<
-              is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>>
+      template<typename _Up, typename _Tpp = typename add_pointer<_Tp>::type,
+              typename = _Require<is_convertible<_Up*, _Tpp>,
+                                  is_same<_Dp, default_delete<_Tp>>>>
        unique_ptr(auto_ptr<_Up>&& __u) noexcept;
 #pragma GCC diagnostic pop
 #endif

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/116529] Construction of unique_ptr with reference type is rejected because of auto_ptr constructor
  2024-08-29  6:24 [Bug libstdc++/116529] New: Construction of unique_ptr with reference type is rejected because of auto_ptr constructor luigighiron at gmail dot com
  2024-08-29 10:17 ` [Bug libstdc++/116529] " redi at gcc dot gnu.org
  2024-08-29 10:22 ` redi at gcc dot gnu.org
@ 2024-08-29 10:24 ` redi at gcc dot gnu.org
  2024-08-30 10:43 ` redi at gcc dot gnu.org
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: redi at gcc dot gnu.org @ 2024-08-29 10:24 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Halalaluyafail3 from comment #0)
> haven't seen any restrictions on using a unique_ptr with a reference type so
> I assume that this is OK (since C++17).

I'm not sure if that's actually intended, it's probably just an accident that
it works.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/116529] Construction of unique_ptr with reference type is rejected because of auto_ptr constructor
  2024-08-29  6:24 [Bug libstdc++/116529] New: Construction of unique_ptr with reference type is rejected because of auto_ptr constructor luigighiron at gmail dot com
                   ` (2 preceding siblings ...)
  2024-08-29 10:24 ` redi at gcc dot gnu.org
@ 2024-08-30 10:43 ` redi at gcc dot gnu.org
  2024-08-30 18:45 ` luigighiron at gmail dot com
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: redi at gcc dot gnu.org @ 2024-08-30 10:43 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Do you have an actual use case for this, or are you just reporting it because
there's divergence between implementations?

I raised it with the standards committee and everybody agrees that we should
not support this, so I'm creating a new library issue for it.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/116529] Construction of unique_ptr with reference type is rejected because of auto_ptr constructor
  2024-08-29  6:24 [Bug libstdc++/116529] New: Construction of unique_ptr with reference type is rejected because of auto_ptr constructor luigighiron at gmail dot com
                   ` (3 preceding siblings ...)
  2024-08-30 10:43 ` redi at gcc dot gnu.org
@ 2024-08-30 18:45 ` luigighiron at gmail dot com
  2024-09-03 10:08 ` de34 at live dot cn
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: luigighiron at gmail dot com @ 2024-08-30 18:45 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #5 from Halalaluyafail3 <luigighiron at gmail dot com> ---
(In reply to Jonathan Wakely from comment #4)
> Do you have an actual use case for this, or are you just reporting it
> because there's divergence between implementations?
> 
> I raised it with the standards committee and everybody agrees that we should
> not support this, so I'm creating a new library issue for it.

I have no use case for this, I only found this when looking at the edge cases
of unique_ptr. If you're looking to make this invalid there is another edge
case that I think should also be made invalid:

#include<memory>
#include<iostream>
int main(){
    struct deleter{
        using pointer=float*;
        void operator()(pointer)const{}
    };
    float f=42;
    std::unique_ptr<const int,deleter>u(&f);
    std::cout<<*u<<'\n';
}

The restrictions on unique_ptr don't disallow cases where pointer is unrelated
to the element_type which allows awkward cases like this.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/116529] Construction of unique_ptr with reference type is rejected because of auto_ptr constructor
  2024-08-29  6:24 [Bug libstdc++/116529] New: Construction of unique_ptr with reference type is rejected because of auto_ptr constructor luigighiron at gmail dot com
                   ` (4 preceding siblings ...)
  2024-08-30 18:45 ` luigighiron at gmail dot com
@ 2024-09-03 10:08 ` de34 at live dot cn
  2024-09-03 13:45 ` redi at gcc dot gnu.org
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: de34 at live dot cn @ 2024-09-03 10:08 UTC (permalink / raw)
  To: gcc-bugs

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

Jiang An <de34 at live dot cn> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |de34 at live dot cn

--- Comment #6 from Jiang An <de34 at live dot cn> ---
(In reply to Jonathan Wakely from comment #3)
> (In reply to Halalaluyafail3 from comment #0)
> > haven't seen any restrictions on using a unique_ptr with a reference type so
> > I assume that this is OK (since C++17).
> 
> I'm not sure if that's actually intended, it's probably just an accident
> that it works.

In C++14/N4140 [unique.ptr.single.ctor]
(https://timsong-cpp.github.io/cppwp/n4140/unique.ptr.single.ctor#24), the
removed wording was

> Remarks: This constructor shall not participate in overload resolution unless
> U* is implicitly convertible to T* and D is the same type as default_delete<T>.


https://cplusplus.github.io/LWG/issue4032 may be related. Per the comments you
made, perhaps there should be substitution failure when T* is ill-formed?

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/116529] Construction of unique_ptr with reference type is rejected because of auto_ptr constructor
  2024-08-29  6:24 [Bug libstdc++/116529] New: Construction of unique_ptr with reference type is rejected because of auto_ptr constructor luigighiron at gmail dot com
                   ` (5 preceding siblings ...)
  2024-09-03 10:08 ` de34 at live dot cn
@ 2024-09-03 13:45 ` redi at gcc dot gnu.org
  2024-09-03 13:46 ` redi at gcc dot gnu.org
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: redi at gcc dot gnu.org @ 2024-09-03 13:45 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> ---
That's what this does:

--- a/libstdc++-v3/include/bits/unique_ptr.h
+++ b/libstdc++-v3/include/bits/unique_ptr.h
@@ -379,8 +379,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
       /// Converting constructor from @c auto_ptr
-      template<typename _Up, typename = _Require<
-              is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>>
+      template<typename _Up,
+              typename = _Require<is_convertible<_Up*, pointer>,
+                                  is_same<_Dp, default_delete<_Tp>>>>
        unique_ptr(auto_ptr<_Up>&& __u) noexcept;
 #pragma GCC diagnostic pop
 #endif

This is equivalent, because when D must be default_delete<T>, pointer must be
T*. But the ill-formed type now occurs during substitution.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/116529] Construction of unique_ptr with reference type is rejected because of auto_ptr constructor
  2024-08-29  6:24 [Bug libstdc++/116529] New: Construction of unique_ptr with reference type is rejected because of auto_ptr constructor luigighiron at gmail dot com
                   ` (6 preceding siblings ...)
  2024-09-03 13:45 ` redi at gcc dot gnu.org
@ 2024-09-03 13:46 ` redi at gcc dot gnu.org
  2024-09-20 22:50 ` cvs-commit at gcc dot gnu.org
  2024-09-23 19:24 ` cvs-commit at gcc dot gnu.org
  9 siblings, 0 replies; 11+ messages in thread
From: redi at gcc dot gnu.org @ 2024-09-03 13:46 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #8 from Jonathan Wakely <redi at gcc dot gnu.org> ---
I opened https://cplusplus.github.io/LWG/issue4144 for the unique_ptr<T&,D>
case and https://cplusplus.github.io/LWG/issue4148 for the dangling reference
case.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/116529] Construction of unique_ptr with reference type is rejected because of auto_ptr constructor
  2024-08-29  6:24 [Bug libstdc++/116529] New: Construction of unique_ptr with reference type is rejected because of auto_ptr constructor luigighiron at gmail dot com
                   ` (7 preceding siblings ...)
  2024-09-03 13:46 ` redi at gcc dot gnu.org
@ 2024-09-20 22:50 ` cvs-commit at gcc dot gnu.org
  2024-09-23 19:24 ` cvs-commit at gcc dot gnu.org
  9 siblings, 0 replies; 11+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2024-09-20 22:50 UTC (permalink / raw)
  To: gcc-bugs

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

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

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

commit r15-3747-ga001d515059ba4647169f8c17967d08bbe41cb7a
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu Aug 29 13:47:15 2024 +0100

    libstdc++: Avoid forming T* in unique_ptr(auto_ptr<U>&&) constraints
[PR116529]

    PR 116529 shows that std::unique_ptr<X&, D> is currently unusable
    because the constructor taking std::auto_ptr (which is a non-standard
    extension since C++17) tries to form the invalid type X&* during
    overload resolution. We can use the `pointer` type in the constructor
    constraints, instead of trying to form an invalid type. The
    std::auto_ptr constructor can never actually match for the case where
    element_type is a reference, so we just need it to produce a
    substitution failure instead of being ill-formed.

    LWG 4144 might make std::unique_ptr<X&, D> ill-formed, which would
    invalidate this new test. We would have to remove this test in that
    case. Using `pointer` in the constructor from std::auto_ptr would not be
    needed to support the std::unique_ptr<X&, D> case, but would not cause
    any harm either.

    libstdc++-v3/ChangeLog:

            PR libstdc++/116529
            * include/bits/unique_ptr.h (unique_ptr(auto_ptr<U>&&)):
            Use pointer instead of T*.
            * testsuite/20_util/unique_ptr/creation/116529.cc: New test.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug libstdc++/116529] Construction of unique_ptr with reference type is rejected because of auto_ptr constructor
  2024-08-29  6:24 [Bug libstdc++/116529] New: Construction of unique_ptr with reference type is rejected because of auto_ptr constructor luigighiron at gmail dot com
                   ` (8 preceding siblings ...)
  2024-09-20 22:50 ` cvs-commit at gcc dot gnu.org
@ 2024-09-23 19:24 ` cvs-commit at gcc dot gnu.org
  9 siblings, 0 replies; 11+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2024-09-23 19:24 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #10 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-14 branch has been updated by Jonathan Wakely
<redi@gcc.gnu.org>:

https://gcc.gnu.org/g:4d88724c2d804e126d63aed77fa8c2c333e99396

commit r14-10708-g4d88724c2d804e126d63aed77fa8c2c333e99396
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu Aug 29 13:47:15 2024 +0100

    libstdc++: Avoid forming T* in unique_ptr(auto_ptr<U>&&) constraints
[PR116529]

    PR 116529 shows that std::unique_ptr<X&, D> is currently unusable
    because the constructor taking std::auto_ptr (which is a non-standard
    extension since C++17) tries to form the invalid type X&* during
    overload resolution. We can use the `pointer` type in the constructor
    constraints, instead of trying to form an invalid type. The
    std::auto_ptr constructor can never actually match for the case where
    element_type is a reference, so we just need it to produce a
    substitution failure instead of being ill-formed.

    LWG 4144 might make std::unique_ptr<X&, D> ill-formed, which would
    invalidate this new test. We would have to remove this test in that
    case. Using `pointer` in the constructor from std::auto_ptr would not be
    needed to support the std::unique_ptr<X&, D> case, but would not cause
    any harm either.

    libstdc++-v3/ChangeLog:

            PR libstdc++/116529
            * include/bits/unique_ptr.h (unique_ptr(auto_ptr<U>&&)):
            Use pointer instead of T*.
            * testsuite/20_util/unique_ptr/creation/116529.cc: New test.

    (cherry picked from commit a001d515059ba4647169f8c17967d08bbe41cb7a)

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2024-09-23 19:24 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-08-29  6:24 [Bug libstdc++/116529] New: Construction of unique_ptr with reference type is rejected because of auto_ptr constructor luigighiron at gmail dot com
2024-08-29 10:17 ` [Bug libstdc++/116529] " redi at gcc dot gnu.org
2024-08-29 10:22 ` redi at gcc dot gnu.org
2024-08-29 10:24 ` redi at gcc dot gnu.org
2024-08-30 10:43 ` redi at gcc dot gnu.org
2024-08-30 18:45 ` luigighiron at gmail dot com
2024-09-03 10:08 ` de34 at live dot cn
2024-09-03 13:45 ` redi at gcc dot gnu.org
2024-09-03 13:46 ` redi at gcc dot gnu.org
2024-09-20 22:50 ` cvs-commit at gcc dot gnu.org
2024-09-23 19:24 ` cvs-commit at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).