Bug 77987 - [6/7 Regression] unique_ptr<T[]> reset rejects cv-compatible pointers
Summary: [6/7 Regression] unique_ptr<T[]> reset rejects cv-compatible pointers
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 6.2.0
: P3 normal
Target Milestone: 6.3
Assignee: Jonathan Wakely
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-10-14 17:34 UTC by Barry Revzin
Modified: 2016-10-17 18:25 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work: 5.4.0
Known to fail: 6.2.0, 7.0
Last reconfirmed: 2016-10-14 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Barry Revzin 2016-10-14 17:34:40 UTC
#include <memory>

int main() {
    std::unique_ptr<const char[]> p;
    p.reset(new char[1]);
}

fails to compile with due to reset invoking swap on two different types. However, this code should be well-formed per N4089.
Comment 1 Jonathan Wakely 2016-10-15 00:35:12 UTC
Seems simple enough to fix:

@@ -608,8 +608,9 @@
                   >
                >>
       void
-      reset(_Up __p) noexcept
+      reset(_Up __ptr) noexcept
       {
+       pointer __p = __ptr;
        using std::swap;
        swap(std::get<0>(_M_t), __p);
        if (__p != nullptr)
Comment 2 Jonathan Wakely 2016-10-17 12:01:16 UTC
Author: redi
Date: Mon Oct 17 12:00:44 2016
New Revision: 241235

URL: https://gcc.gnu.org/viewcvs?rev=241235&root=gcc&view=rev
Log:
PR77987 Fix unique_ptr<T[], D>::reset(U) for T != U

	PR libstdc++/77987
	* include/bits/unique_ptr.h (unique_ptr<T[], D>::reset<U>(U)): Copy
	value to pointer of the correct type to swap, to support conversions
	allowed by LWG 2118 / N4089.
	* testsuite/20_util/unique_ptr/assign/assign_neg.cc: Move test for
	incompatible deleters from ...
	* testsuite/20_util/unique_ptr/assign/cv_qual.cc: ... here.
	* testsuite/20_util/unique_ptr/modifiers/cv_qual.cc: Move tests for
	incompatible pointers to ...
	* testsuite/20_util/unique_ptr/modifiers/reset_neg.cc: ... here. Move
	destructor definition to base class. Test for invalid derived-to-base
	conversion.

Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/include/bits/unique_ptr.h
    trunk/libstdc++-v3/testsuite/20_util/unique_ptr/assign/assign_neg.cc
    trunk/libstdc++-v3/testsuite/20_util/unique_ptr/assign/cv_qual.cc
    trunk/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/cv_qual.cc
    trunk/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc
Comment 3 Jonathan Wakely 2016-10-17 12:24:30 UTC
Fixed on trunk so far.
Comment 4 Jonathan Wakely 2016-10-17 18:21:58 UTC
Author: redi
Date: Mon Oct 17 18:21:26 2016
New Revision: 241276

URL: https://gcc.gnu.org/viewcvs?rev=241276&root=gcc&view=rev
Log:
PR77987 Fix unique_ptr<T[], D>::reset(U) for T != U

	PR libstdc++/77987
	* include/bits/unique_ptr.h (unique_ptr<T[], D>::reset<U>(U)): Copy
	value to pointer of the correct type to swap, to support conversions
	allowed by LWG 2118 / N4089.
	* testsuite/20_util/unique_ptr/assign/assign_neg.cc: Move test for
	incompatible deleters from ...
	* testsuite/20_util/unique_ptr/assign/cv_qual.cc: ... here.
	* testsuite/20_util/unique_ptr/modifiers/cv_qual.cc: Move tests for
	incompatible pointers to ...
	* testsuite/20_util/unique_ptr/modifiers/reset_neg.cc: ... here. Move
	destructor definition to base class. Test for invalid derived-to-base
	conversion.

Modified:
    branches/gcc-6-branch/libstdc++-v3/ChangeLog
    branches/gcc-6-branch/libstdc++-v3/include/bits/unique_ptr.h
    branches/gcc-6-branch/libstdc++-v3/testsuite/20_util/unique_ptr/assign/assign_neg.cc
    branches/gcc-6-branch/libstdc++-v3/testsuite/20_util/unique_ptr/assign/cv_qual.cc
    branches/gcc-6-branch/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/cv_qual.cc
    branches/gcc-6-branch/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc
Comment 5 Jonathan Wakely 2016-10-17 18:25:13 UTC
Fixed for 6.3