Re: [v3 PATCH] Protect allocator-overloads of tuple-from-tuple constructors from cases that would create dangling references.

2016-05-30 Thread Paolo Carlini

Hi Ville,

On 29/05/2016 16:42, Ville Voutilainen wrote:

On 28 May 2016 at 21:25, Ville Voutilainen  wrote:

The fix to avoid binding dangling references to temporaries for tuple's
constructors that take tuples of different type didn't include the fix
for allocator overloads. That was just lazy, and I should feel ashamed.
This patch fixes it, and takes us one step further to pass libc++'s testsuite
for tuple. The added _NonNestedTuple checks could actually be folded
into the recently-added _TMCT alias, but I'll do that as a separate cleanup
patch. For now, this should do as an easy and straightforward fix.

Tested on Linux-x64.

2016-05-28  Ville Voutilainen  

 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.

Since Jonathan is going to be out-of-reach for next week due to a
well-deserved holiday, would it be ok if Paolo approves such patches?
Admittedly, I didn't follow in detail all your latest contributions, but 
sure, if this work goes only in trunk, please go ahead at your ease. We 
can certainly revisit details when Jon comes back, but trunk is 
currently in Stage 1, open for any kind of development work...


Thanks,
Paolo.


Re: [v3 PATCH] Protect allocator-overloads of tuple-from-tuple constructors from cases that would create dangling references.

2016-05-29 Thread Ville Voutilainen
On 28 May 2016 at 21:25, Ville Voutilainen  wrote:
> The fix to avoid binding dangling references to temporaries for tuple's
> constructors that take tuples of different type didn't include the fix
> for allocator overloads. That was just lazy, and I should feel ashamed.
> This patch fixes it, and takes us one step further to pass libc++'s testsuite
> for tuple. The added _NonNestedTuple checks could actually be folded
> into the recently-added _TMCT alias, but I'll do that as a separate cleanup
> patch. For now, this should do as an easy and straightforward fix.
>
> Tested on Linux-x64.
>
> 2016-05-28  Ville Voutilainen  
>
> 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.

Since Jonathan is going to be out-of-reach for next week due to a
well-deserved holiday, would it be ok
if Paolo approves such patches?


[v3 PATCH] Protect allocator-overloads of tuple-from-tuple constructors from cases that would create dangling references.

2016-05-28 Thread Ville Voutilainen
The fix to avoid binding dangling references to temporaries for tuple's
constructors that take tuples of different type didn't include the fix
for allocator overloads. That was just lazy, and I should feel ashamed.
This patch fixes it, and takes us one step further to pass libc++'s testsuite
for tuple. The added _NonNestedTuple checks could actually be folded
into the recently-added _TMCT alias, but I'll do that as a separate cleanup
patch. For now, this should do as an easy and straightforward fix.

Tested on Linux-x64.

2016-05-28  Ville Voutilainen  

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.
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index ea88793..17c8204 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -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::template
 _ConstructibleTuple<_UElements...>()
   && _TMCT<_UElements...>::template
-_ImplicitlyConvertibleTuple<_UElements...>(),
+_ImplicitlyConvertibleTuple<_UElements...>()
+  && _TNTC<_Dummy>::template
+_NonNestedTuple&&>(),
 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&>(__in))
{ }
 
-  template::template
 _ConstructibleTuple<_UElements...>()
   && !_TMCT<_UElements...>::template
-_ImplicitlyConvertibleTuple<_UElements...>(),
+_ImplicitlyConvertibleTuple<_UElements...>()
+  && _TNTC<_Dummy>::template
+_NonNestedTuple&&>(),
 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&>(__in))
{ }
 
-  template::template
 _MoveConstructibleTuple<_UElements...>()
   && _TMCT<_UElements...>::template
-_ImplicitlyMoveConvertibleTuple<_UElements...>(),
+_ImplicitlyMoveConvertibleTuple<_UElements...>()
+  && _TNTC<_Dummy>::template
+_NonNestedTuple&&>(),
 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::template
 _MoveConstructibleTuple<_UElements...>()
   && !_TMCT<_UElements...>::template
-_ImplicitlyMoveConvertibleTuple<_UElements...>(),
+_ImplicitlyMoveConvertibleTuple<_UElements...>()
+  && _TNTC<_Dummy>::template
+_NonNestedTuple&&>(),
 bool>::type=false>
explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
  tuple<_UElements...>&& __in)
diff --git 
a/libstdc++-v3/testsuite/20_util/tuple/cons/nested_tuple_construct.cc 
b/libstdc++-v3/testsuite/20_util/tuple/cons/nested_tuple_construct.cc
index 39a4f73..7f64239 100644
--- a/libstdc++-v3/testsuite/20_util/tuple/cons/nested_tuple_construct.cc
+++ b/libstdc++-v3/testsuite/20_util/tuple/cons/nested_tuple_construct.cc
@@ -63,6 +63,32 @@ void f3()
   std::tuple> t3{std::move(t2)};
 }
 
+void f4()
+{
+  std::allocator a;
+  X v;
+  std::tuple t1{std::allocator_arg, a, v};
+  std::tuple&&> t2{std::allocator_arg, a, std::move(t1)};
+  std::tuple> t3{std::allocator_arg, a, std::move(t2)};
+}
+
+void f5()
+{
+  std::allocator a;
+  X v;
+  std::tuple t1{std::allocator_arg, a, std::move(v)};
+  std::tuple&&> t2{std::allocator_arg, a, std::move(t1)};
+  std::tuple> t3{std::allocator_arg, a, std::move(t2)};
+}
+
+void f6()
+{
+  std::allocator a;
+  std::tuple t1{std::allocator_arg, a, X{}};
+  std::tuple&&> t2{std::allocator_arg, a, std::move(t1)};
+  std::tuple> 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();
+