Protect allocator-overloads of tuple-from-tuple constructors from cases that would create dangling references.
Protect allocator-overloads of tuple-from-tuple constructors from cases that would create dangling references. * include/std/tuple (tuple(allocator_arg_t, const _Alloc&, const tuple<_UElements...>&), tuple(allocator_arg_t, const _Alloc&, tuple<_UElements...>&&)): Add a check for _NonNestedTuple. * testsuite/20_util/tuple/cons/nested_tuple_construct.cc: Adjust. From-SVN: r237106
This commit is contained in:
parent
b2d83bd2c7
commit
7a66745357
@ -1,3 +1,12 @@
|
||||
2016-06-05 Ville Voutilainen <ville.voutilainen@gmail.com>
|
||||
|
||||
Protect allocator-overloads of tuple-from-tuple constructors
|
||||
from cases that would create dangling references.
|
||||
* include/std/tuple (tuple(allocator_arg_t, const _Alloc&,
|
||||
const tuple<_UElements...>&), tuple(allocator_arg_t, const _Alloc&,
|
||||
tuple<_UElements...>&&)): Add a check for _NonNestedTuple.
|
||||
* testsuite/20_util/tuple/cons/nested_tuple_construct.cc: Adjust.
|
||||
|
||||
2016-05-29 Gerald Pfeifer <gerald@pfeifer.com>
|
||||
|
||||
* doc/xml/manual/backwards_compatibility.xml: Adjust
|
||||
|
@ -769,11 +769,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
|
||||
: _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
|
||||
|
||||
template<typename _Alloc, typename... _UElements, typename
|
||||
template<typename _Alloc, typename _Dummy = void,
|
||||
typename... _UElements, typename
|
||||
enable_if<_TMCT<_UElements...>::template
|
||||
_ConstructibleTuple<_UElements...>()
|
||||
&& _TMCT<_UElements...>::template
|
||||
_ImplicitlyConvertibleTuple<_UElements...>(),
|
||||
_ImplicitlyConvertibleTuple<_UElements...>()
|
||||
&& _TNTC<_Dummy>::template
|
||||
_NonNestedTuple<tuple<_UElements...>&&>(),
|
||||
bool>::type=true>
|
||||
tuple(allocator_arg_t __tag, const _Alloc& __a,
|
||||
const tuple<_UElements...>& __in)
|
||||
@ -781,11 +784,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
|
||||
{ }
|
||||
|
||||
template<typename _Alloc, typename... _UElements, typename
|
||||
template<typename _Alloc, typename _Dummy = void,
|
||||
typename... _UElements, typename
|
||||
enable_if<_TMCT<_UElements...>::template
|
||||
_ConstructibleTuple<_UElements...>()
|
||||
&& !_TMCT<_UElements...>::template
|
||||
_ImplicitlyConvertibleTuple<_UElements...>(),
|
||||
_ImplicitlyConvertibleTuple<_UElements...>()
|
||||
&& _TNTC<_Dummy>::template
|
||||
_NonNestedTuple<tuple<_UElements...>&&>(),
|
||||
bool>::type=false>
|
||||
explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
|
||||
const tuple<_UElements...>& __in)
|
||||
@ -793,11 +799,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
|
||||
{ }
|
||||
|
||||
template<typename _Alloc, typename... _UElements, typename
|
||||
template<typename _Alloc, typename _Dummy = void,
|
||||
typename... _UElements, typename
|
||||
enable_if<_TMCT<_UElements...>::template
|
||||
_MoveConstructibleTuple<_UElements...>()
|
||||
&& _TMCT<_UElements...>::template
|
||||
_ImplicitlyMoveConvertibleTuple<_UElements...>(),
|
||||
_ImplicitlyMoveConvertibleTuple<_UElements...>()
|
||||
&& _TNTC<_Dummy>::template
|
||||
_NonNestedTuple<tuple<_UElements...>&&>(),
|
||||
bool>::type=true>
|
||||
tuple(allocator_arg_t __tag, const _Alloc& __a,
|
||||
tuple<_UElements...>&& __in)
|
||||
@ -805,11 +814,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
|
||||
{ }
|
||||
|
||||
template<typename _Alloc, typename... _UElements, typename
|
||||
template<typename _Alloc, typename _Dummy = void,
|
||||
typename... _UElements, typename
|
||||
enable_if<_TMCT<_UElements...>::template
|
||||
_MoveConstructibleTuple<_UElements...>()
|
||||
&& !_TMCT<_UElements...>::template
|
||||
_ImplicitlyMoveConvertibleTuple<_UElements...>(),
|
||||
_ImplicitlyMoveConvertibleTuple<_UElements...>()
|
||||
&& _TNTC<_Dummy>::template
|
||||
_NonNestedTuple<tuple<_UElements...>&&>(),
|
||||
bool>::type=false>
|
||||
explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
|
||||
tuple<_UElements...>&& __in)
|
||||
|
@ -63,6 +63,32 @@ void f3()
|
||||
std::tuple<std::tuple<X>> t3{std::move(t2)};
|
||||
}
|
||||
|
||||
void f4()
|
||||
{
|
||||
std::allocator<X> a;
|
||||
X v;
|
||||
std::tuple<X> t1{std::allocator_arg, a, v};
|
||||
std::tuple<std::tuple<X>&&> t2{std::allocator_arg, a, std::move(t1)};
|
||||
std::tuple<std::tuple<X>> t3{std::allocator_arg, a, std::move(t2)};
|
||||
}
|
||||
|
||||
void f5()
|
||||
{
|
||||
std::allocator<X> a;
|
||||
X v;
|
||||
std::tuple<X> t1{std::allocator_arg, a, std::move(v)};
|
||||
std::tuple<std::tuple<X>&&> t2{std::allocator_arg, a, std::move(t1)};
|
||||
std::tuple<std::tuple<X>> t3{std::allocator_arg, a, std::move(t2)};
|
||||
}
|
||||
|
||||
void f6()
|
||||
{
|
||||
std::allocator<X> a;
|
||||
std::tuple<X> t1{std::allocator_arg, a, X{}};
|
||||
std::tuple<std::tuple<X>&&> t2{std::allocator_arg, a, std::move(t1)};
|
||||
std::tuple<std::tuple<X>> t3{std::allocator_arg, a, std::move(t2)};
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
f();
|
||||
@ -74,4 +100,13 @@ int main()
|
||||
f3();
|
||||
VERIFY(result == "DefMoveDtorMoveDtorDtor");
|
||||
result = "";
|
||||
f4();
|
||||
VERIFY(result == "DefCopyMoveDtorDtorDtor");
|
||||
result = "";
|
||||
f5();
|
||||
VERIFY(result == "DefMoveMoveDtorDtorDtor");
|
||||
result = "";
|
||||
f6();
|
||||
VERIFY(result == "DefMoveDtorMoveDtorDtor");
|
||||
result = "";
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user