Commit f3344569 by Ville Voutilainen Committed by Ville Voutilainen

Implement N4089 Safe conversions in unique_ptr<T[]> (LWG 2118) and N4366 LWG 2228...

2015-08-08  Ville Voutilainen  <ville.voutilainen@gmail.com>

	Implement N4089 Safe conversions in unique_ptr<T[]> (LWG 2118)
	and N4366 LWG 2228: Missing SFINAE rule in unique_ptr
	templated assignment
	* include/bits/unique_ptr.h
	(__remove_cv, __is_derived_Tp): Remove.
	(default_delete::default_delete(const default_delete<_Up[]>)):
	Constrain with array convertibility.
	(default_delete::operator(_Up*)): Turn into a template,
	constrain with array convertibility.
	(__safe_conversion_up): New, single object version.
	(unique_ptr(unique_ptr<_Up, _Ep>&&)): Constrain with deleter
	convertibility.
	(unique_ptr::operator=(unique_ptr<_Up, _Ep>&&)): Likewise, and add
	is_assignable as a constraint.
	(__safe_conversion_up): Array version, renamed from __safe_conversion,
	updated to implement N4089.
	(__safe_conversion_raw): New.
	(unique_ptr(_Up)): Turn into a template, constrain with array
	convertibility.
	(unique_ptr(_Up,
        typename conditional<is_reference<deleter_type>::value,
        deleter_type, const deleter_type&>::type)): Likewise.
	(unique_ptr(_Up, typename
 	remove_reference<deleter_type>::type&&)): Likewise.
	(unique_ptr(unique_ptr<_Up, _Ep>&&)): Likewise.
	(operator=(unique_ptr<_Up, _Ep>&&)): Likewise, and add
	is_assignable as a constraint (array version).
	(reset(_Up)): Turn into a template, constrain with array
	convertibility.
	(reset(nullptr_t)): New.
	* testsuite/20_util/default_delete/48631_neg.cc: Adjust.
	* testsuite/20_util/unique_ptr/assign/48635.cc: Likewise.
	* testsuite/20_util/unique_ptr/assign/48635_neg.cc: Likewise.
	* testsuite/20_util/unique_ptr/assign/cv_qual.cc: Likewise.
	* testsuite/20_util/unique_ptr/cons/cv_qual.cc: Likewise.
	* testsuite/20_util/unique_ptr/dr2228.cc: New.
	* testsuite/20_util/unique_ptr/modifiers/cv_qual.cc: Adjust.

From-SVN: r226733
parent 0d251765
2015-08-08 Ville Voutilainen <ville.voutilainen@gmail.com>
Implement N4089 Safe conversions in unique_ptr<T[]> (LWG 2118)
and N4366 LWG 2228: Missing SFINAE rule in unique_ptr
templated assignment
* include/bits/unique_ptr.h
(__remove_cv, __is_derived_Tp): Remove.
(default_delete::default_delete(const default_delete<_Up[]>)):
Constrain with array convertibility.
(default_delete::operator(_Up*)): Turn into a template,
constrain with array convertibility.
(__safe_conversion_up): New, single object version.
(unique_ptr(unique_ptr<_Up, _Ep>&&)): Constrain with deleter
convertibility.
(unique_ptr::operator=(unique_ptr<_Up, _Ep>&&)): Likewise, and add
is_assignable as a constraint.
(__safe_conversion_up): Array version, renamed from __safe_conversion,
updated to implement N4089.
(__safe_conversion_raw): New.
(unique_ptr(_Up)): Turn into a template, constrain with array
convertibility.
(unique_ptr(_Up,
typename conditional<is_reference<deleter_type>::value,
deleter_type, const deleter_type&>::type)): Likewise.
(unique_ptr(_Up, typename
remove_reference<deleter_type>::type&&)): Likewise.
(unique_ptr(unique_ptr<_Up, _Ep>&&)): Likewise.
(operator=(unique_ptr<_Up, _Ep>&&)): Likewise, and add
is_assignable as a constraint (array version).
(reset(_Up)): Turn into a template, constrain with array
convertibility.
(reset(nullptr_t)): New.
* testsuite/20_util/default_delete/48631_neg.cc: Adjust.
* testsuite/20_util/unique_ptr/assign/48635.cc: Likewise.
* testsuite/20_util/unique_ptr/assign/48635_neg.cc: Likewise.
* testsuite/20_util/unique_ptr/assign/cv_qual.cc: Likewise.
* testsuite/20_util/unique_ptr/cons/cv_qual.cc: Likewise.
* testsuite/20_util/unique_ptr/dr2228.cc: New.
* testsuite/20_util/unique_ptr/modifiers/cv_qual.cc: Adjust.
2015-08-05 Nikolai Bozhenov <n.bozhenov@samsung.com>
* testsuite/20_util/enable_shared_from_this/cons/constexpr.cc: Remove
......
......@@ -26,6 +26,5 @@ struct D : B { };
// libstdc++/48631
D d;
std::default_delete<B[]> db;
typedef decltype(db(&d)) type; // { dg-error "use of deleted function" }
// { dg-prune-output "declared" }
// { dg-prune-output "invalid" }
typedef decltype(db(&d)) type; // { dg-error "no match" }
// { dg-error "no type" "" { target *-*-* } 106 }
......@@ -59,16 +59,8 @@ void test01()
DDeleter dd;
std::unique_ptr<int, DDeleter&> p1t(nullptr, dd);
std::unique_ptr<int, Deleter&> p2t(nullptr, d);
p2t = std::move(p1t);
std::unique_ptr<int[], Deleter&> p1a(nullptr, d), p2a(nullptr, d);
p2a = std::move(p1a);
std::unique_ptr<int[], DDeleter&> p1at(nullptr, dd);
std::unique_ptr<int[], Deleter&> p2at(nullptr, d);
p2at = std::move(p1at);
}
int main()
......
......@@ -24,7 +24,7 @@ struct D;
struct B
{
B& operator=(D&) = delete; // { dg-error "declared here" }
B& operator=(D&) = delete;
template<class T>
void operator()(T*) const {}
......@@ -39,12 +39,14 @@ void f()
D d;
std::unique_ptr<int, B&> ub(nullptr, b);
std::unique_ptr<int, B> ub2(nullptr, b);
std::unique_ptr<int, D&> ud(nullptr, d);
ub = std::move(ud);
// { dg-error "use of deleted function" "" { target *-*-* } 272 }
ub = std::move(ud); // { dg-error "no match" }
ub2 = ud; // { dg-error "no match" }
// { dg-error "no type" "" { target *-*-* } 269 }
std::unique_ptr<int[], B&> uba(nullptr, b);
std::unique_ptr<int[], D&> uda(nullptr, d);
uba = std::move(uda);
// { dg-error "use of deleted function" "" { target *-*-* } 517 }
uba = std::move(uda); // { dg-error "no match" }
// { dg-error "no type" "" { target *-*-* } 537 }
}
......@@ -82,8 +82,10 @@ struct deleter
void
test04()
{
// Allow conversions from user-defined pointer-like types
// Disallow conversions from incompatible deleter
std::unique_ptr<B[], deleter<A_pointer>> p;
std::unique_ptr<A[], deleter<A*>> upA;
upA = std::move(p);
upA = std::move(p); // { dg-error "no match" }
// { dg-error "no type" "" { target *-*-* } 537 }
// { dg-error "no matching function" "" { target *-*-* } 614 }
}
......@@ -88,11 +88,25 @@ void
test07()
{
// Allow conversions from user-defined pointer-like types
// for the single-object version
A_pointer p;
std::unique_ptr<A[]> upA(p);
std::unique_ptr<const A[]> cA(p);
std::unique_ptr<volatile A[]> vA(p);
std::unique_ptr<const volatile A[]> cvA(p);
std::unique_ptr<A> upA(p);
std::unique_ptr<const A> cA(p);
std::unique_ptr<volatile A> vA(p);
std::unique_ptr<const volatile A> cvA(p);
// Allow conversions from user-defined pointer-like types
// for the array version when the type is converted explicitly
std::unique_ptr<A[]> upA2((A*)p);
std::unique_ptr<const A[]> cA2((A*)p);
std::unique_ptr<volatile A[]> vA2((A*)p);
std::unique_ptr<const volatile A[]> cvA2((A*)p);
// Disallow conversions from user-defined pointer-like types
// for the array version
std::unique_ptr<A[]> upA3(p); // { dg-error "no matching function" }
std::unique_ptr<const A[]> cA3(p); // { dg-error "no matching function" }
std::unique_ptr<volatile A[]> vA3(p); // { dg-error "no matching function" }
std::unique_ptr<const volatile A[]> cvA3(p); // { dg-error "no matching function" }
// { dg-error "no type" "" { target *-*-* } 445 }
}
template<typename T>
......@@ -108,8 +122,8 @@ struct deleter
void
test08()
{
// Allow conversions from user-defined pointer-like types
// Disallow conversions from non-assignable deleter
std::unique_ptr<B[], deleter<A_pointer>> p;
std::unique_ptr<A[], deleter<A*>> upA(std::move(p));
std::unique_ptr<A[], deleter<A*>> upA(std::move(p)); // { dg-error "no matching function" }
}
// { dg-options "-std=gnu++11" }
// { dg-do compile }
// Copyright (C) 2015 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
#include <memory>
#include <type_traits>
struct do_nothing
{
template <class T>
void operator()(T*) {}
};
int
main()
{
int i = 0;
std::unique_ptr<int, do_nothing> p1(&i);
std::unique_ptr<int> p2;
static_assert(!std::is_assignable<decltype(p2), decltype(p1)>::value, "");
}
......@@ -66,14 +66,36 @@ struct A_pointer { operator A*() const { return nullptr; } };
void
test07()
{
// Allow conversions from user-defined pointer-like types
A_pointer p;
std::unique_ptr<A[]> upA;
// Allow conversions from user-defined pointer-like types
// for the single-object version
std::unique_ptr<A> upA;
upA.reset(p);
std::unique_ptr<const A[]> cA;
std::unique_ptr<const A> cA;
cA.reset(p);
std::unique_ptr<volatile A[]> vA;
std::unique_ptr<volatile A> vA;
vA.reset(p);
std::unique_ptr<const volatile A[]> cvA;
std::unique_ptr<const volatile A> cvA;
cvA.reset(p);
// Allow conversions from user-defined pointer-like types
// for the array version when the type is converted explicitly
std::unique_ptr<A[]> upA2;
upA2.reset((A*)p);
std::unique_ptr<const A[]> cA2;
cA2.reset((A*)p);
std::unique_ptr<volatile A[]> vA2;
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 }
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment