[v3 PATCH] Avoid endless run-time recursion for copying single-element tuples where the element type is by-value constructible from any type

Ville Voutilainen ville.voutilainen@gmail.com
Sun May 8 11:44:00 GMT 2016


Tested on Linux-PPC64.

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

    Avoid endless run-time recursion for copying single-element
    tuples where the element type is by-value constructible
    from any type.
     * include/std/tuple (_TC<>::_NotSameTuple): New.
     * include/std/tuple (tuple(_UElements&&...): Use it.
    * testsuite/20_util/tuple/cons/element_accepts_anything_byval.cc: New.
-------------- next part --------------
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 53f3184..7522e43 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -500,6 +500,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                      __not_<is_constructible<_Elements..., _SrcTuple>>
               >::value;
     }
+    template<typename... _UElements>
+    static constexpr bool _NotSameTuple()
+    {
+      return  __not_<is_same<tuple<_Elements...>,
+			     typename remove_const<
+			       typename remove_reference<_UElements...>::type
+			       >::type>>::value;
+    }
   };
 
   template<typename... _Elements>
@@ -534,6 +542,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     {
       return true;
     }
+    template<typename... _UElements>
+    static constexpr bool _NotSameTuple()
+    {
+      return  true;
+    }
   };
 
   /// Primary class template, tuple
@@ -611,7 +624,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                       _Elements...>;
 
       template<typename... _UElements, typename
-        enable_if<_TMC<_UElements...>::template
+	       enable_if<
+		  _TC<sizeof...(_UElements) == 1, _Elements...>::template
+		    _NotSameTuple<_UElements...>()
+		  && _TMC<_UElements...>::template
                     _MoveConstructibleTuple<_UElements...>()
                   && _TMC<_UElements...>::template
                     _ImplicitlyMoveConvertibleTuple<_UElements...>()
@@ -621,7 +637,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
         : _Inherited(std::forward<_UElements>(__elements)...) { }
 
       template<typename... _UElements, typename
-        enable_if<_TMC<_UElements...>::template
+        enable_if<
+		  _TC<sizeof...(_UElements) == 1, _Elements...>::template
+		    _NotSameTuple<_UElements...>()
+		  && _TMC<_UElements...>::template
                     _MoveConstructibleTuple<_UElements...>()
                   && !_TMC<_UElements...>::template
                     _ImplicitlyMoveConvertibleTuple<_UElements...>()
diff --git a/libstdc++-v3/testsuite/20_util/tuple/cons/element_accepts_anything_byval.cc b/libstdc++-v3/testsuite/20_util/tuple/cons/element_accepts_anything_byval.cc
new file mode 100644
index 0000000..fe9bea6
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/tuple/cons/element_accepts_anything_byval.cc
@@ -0,0 +1,30 @@
+// Copyright (C) 2016 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 <tuple>
+using namespace std;
+
+struct Something {
+    Something() { }
+    template <typename T> Something(T) { }
+};
+
+int main() {
+    tuple<Something> t1;
+    tuple<Something> t2 = t1;
+}
+


More information about the Gcc-patches mailing list