aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2016-10-17 13:00:44 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2016-10-17 13:00:44 +0100
commit74cf9664e8a767a329131413de2271a4aae7488a (patch)
tree0ef4ef2ed5d22135910b345867ec3a81dc9c5f17 /libstdc++-v3
parent594ef205ae28bdd8d32ff141b41cc08158b84552 (diff)
downloadgcc-74cf9664e8a767a329131413de2271a4aae7488a.zip
gcc-74cf9664e8a767a329131413de2271a4aae7488a.tar.gz
gcc-74cf9664e8a767a329131413de2271a4aae7488a.tar.bz2
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. From-SVN: r241235
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog13
-rw-r--r--libstdc++-v3/include/bits/unique_ptr.h7
-rw-r--r--libstdc++-v3/testsuite/20_util/unique_ptr/assign/assign_neg.cc21
-rw-r--r--libstdc++-v3/testsuite/20_util/unique_ptr/assign/cv_qual.cc23
-rw-r--r--libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/cv_qual.cc11
-rw-r--r--libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc28
6 files changed, 62 insertions, 41 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index b31c1dd..ed57281 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,18 @@
2016-10-17 Jonathan Wakely <jwakely@redhat.com>
+ 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.
+
* doc/xml/manual/status_cxx2017.xml: Update status.
* doc/html/*: Regenerate.
* include/bits/deque.tcc (deque::emplace_front, deque::emplace_back):
diff --git a/libstdc++-v3/include/bits/unique_ptr.h b/libstdc++-v3/include/bits/unique_ptr.h
index 15ef8a8..a36794d 100644
--- a/libstdc++-v3/include/bits/unique_ptr.h
+++ b/libstdc++-v3/include/bits/unique_ptr.h
@@ -610,10 +610,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void
reset(_Up __p) noexcept
{
+ pointer __ptr = __p;
using std::swap;
- swap(std::get<0>(_M_t), __p);
- if (__p != nullptr)
- get_deleter()(__p);
+ swap(std::get<0>(_M_t), __ptr);
+ if (__ptr != nullptr)
+ get_deleter()(__ptr);
}
void reset(nullptr_t = nullptr) noexcept
diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/assign/assign_neg.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/assign/assign_neg.cc
index 842b6ed..9142e61 100644
--- a/libstdc++-v3/testsuite/20_util/unique_ptr/assign/assign_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/unique_ptr/assign/assign_neg.cc
@@ -48,4 +48,25 @@ test03()
std::unique_ptr<int[2]> p2 = p1; // { dg-error "deleted" }
}
+struct base_pointer { operator base*() const { return nullptr; } };
+
+template<typename T>
+struct deleter
+{
+ deleter() = default;
+ template<typename U>
+ deleter(const deleter<U>) { }
+ typedef T pointer;
+ void operator()(T) const { }
+};
+
+void
+test04()
+{
+ // Disallow conversions from incompatible deleter
+ std::unique_ptr<derived[], deleter<base_pointer>> p;
+ std::unique_ptr<base[], deleter<base*>> upA;
+ upA = std::move(p); // { dg-error "no match" }
+}
+
// { dg-prune-output "include" }
diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/assign/cv_qual.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/assign/cv_qual.cc
index 793499d..7add5a9 100644
--- a/libstdc++-v3/testsuite/20_util/unique_ptr/assign/cv_qual.cc
+++ b/libstdc++-v3/testsuite/20_util/unique_ptr/assign/cv_qual.cc
@@ -65,26 +65,3 @@ test03()
std::unique_ptr<const volatile A[]> cvA;
cvA = std::move(upA);
}
-
-struct A_pointer { operator A*() const { return nullptr; } };
-
-template<typename T>
-struct deleter
-{
- deleter() = default;
- template<typename U>
- deleter(const deleter<U>) { }
- typedef T pointer;
- void operator()(T) const { }
-};
-
-void
-test04()
-{
- // Disallow conversions from incompatible deleter
- std::unique_ptr<B[], deleter<A_pointer>> p;
- std::unique_ptr<A[], deleter<A*>> upA;
- upA = std::move(p); // { dg-error "no match" }
- // { dg-error "no type" "" { target *-*-* } 537 }
- // { dg-error "no matching function" "" { target *-*-* } 614 }
-}
diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/cv_qual.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/cv_qual.cc
index 0284563..f92949b 100644
--- a/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/cv_qual.cc
+++ b/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/cv_qual.cc
@@ -86,15 +86,4 @@ test07()
vA2.reset((A*)p);
std::unique_ptr<const volatile A[]> cvA2;
cvA2.reset((A*)p);
- // Disallow conversions from user-defined pointer-like types
- // for the array version
- std::unique_ptr<A[]> upA3;
- upA3.reset(p); // { dg-error "no matching function" }
- std::unique_ptr<const A[]> cA3;
- cA3.reset(p); // { dg-error "no matching function" }
- std::unique_ptr<volatile A[]> vA3;
- vA3.reset(p); // { dg-error "no matching function" }
- std::unique_ptr<const volatile A[]> cvA3;
- cvA3.reset(p); // { dg-error "no matching function" }
- // { dg-error "no matching function" "" { target *-*-* } 614 }
}
diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc
index d2ed03c..cb5f2e6 100644
--- a/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc
@@ -21,17 +21,37 @@
struct A
{
+ virtual ~A() { }
};
struct B : A
{
- virtual ~B() { }
};
-void test01()
+void
+test01()
{
std::unique_ptr<B[]> up;
- up.reset(new A[3]); // { dg-error "" }
+ up.reset(new A[3]); // { dg-error "no matching function" }
+
+ std::unique_ptr<A[]> up2;
+ up2.reset(new B[3]); // { dg-error "no matching function" }
}
-// { dg-prune-output "include" }
+struct A_pointer { operator A*() const { return nullptr; } };
+
+void
+test02()
+{
+ A_pointer p;
+ // Disallow conversions from user-defined pointer-like types
+ // for the array version
+ std::unique_ptr<A[]> upA3;
+ upA3.reset(p); // { dg-error "no matching function" }
+ std::unique_ptr<const A[]> cA3;
+ cA3.reset(p); // { dg-error "no matching function" }
+ std::unique_ptr<volatile A[]> vA3;
+ vA3.reset(p); // { dg-error "no matching function" }
+ std::unique_ptr<const volatile A[]> cvA3;
+ cvA3.reset(p); // { dg-error "no matching function" }
+}